perm filename BCPL.DBA[UP,DOC]1 blob sn#095996 filedate 1974-04-08 generic text, type T, neo UTF8





                 The BCPL Reference Manual


     This  manual  was  originally  written  by  Martin
     Richards  at  MIT  Project  MAC  in  1964.  It was
     revised by Henry Ancona at MIT Lincoln  Laboratory
     in 1967, and by Paul Rovner and Jerry Burchfiel at
     BBN  in  1973.   The  section  on  structures  was
     originally  written  by  Art  Evans at MIT Lincoln
     Laboratory.

BCPL Reference Manual                               Page   2
Introduction


                          ABSTRACT




     BCPL is a simple  recursive  programming  language  designed  for
compiler  writing  and  system  programming;  it  was derived from CPL
(Combined Programming Language [1]) by removing those features of  the
language  which  make compilation difficult, namely, the type and mode
matching rules and the variety of  definition  structures  with  their
associated scope rules.

     BCPL  is  a  language  which  is  readable,  easy  to  learn  and
efficient.   It  is made self-consistent and easy to define accurately
by an underlying structure based on a simple idealized object machine.
The  treatment  of  data  types is unusual and it allows the power and
convenience of a language with dynamically varying types and  yet  the
efficiency of FORTRAN.  BCPL has been used successfully to implement a
number of languages and has proved to be a very useful tool for system
programming.  The BCPL compiler itself is written in BCPL and has been
designed to be easy to transfer to other machines.

BCPL Reference Manual                               Page   3
Introduction


                     Table of Contents
                     _____ __ ________

1.   Acknowledgements

2.   Introduction

3.   Fundamental Concepts of BCPL
     3.1     The Object Machine
     3.2     Names, Variables, and Manifest Constants
     3.3     Addresses
     3.4     Simple Assignment
     3.5     The lv Operator
                 __
     3.6     The rv Operator
                 __
     3.7     Data Structures
     3.8     Data Types

4.   Expressions
     4.1     Primary Expressions
           4.1.1   Numerical Constants
           4.1.2   Character Constants
           4.1.3   String Constants
           4.1.4   Names
           4.1.5   Boolean Constants
           4.1.6   Unspecified Initial Value
           4.1.7   Parenthesized Expressions
           4.1.8   valof Expressions
                   _____
           4.1.9   Function Applications
           4.1.10  Vector Applications
           4.1.11  lv Expressions
                   __
           4.1.12  rv Expressions
                   __
           4.1.13  Half-word Extraction Expressions
           4.1.14  Quarter-word Extraction Expressions
           4.1.15  Structure References
     4.2     Arithmetic Expressions
     4.3     Relational Expressions
     4.4     Shift Expressions
     4.5     Logical Expressions
     4.6     Half-word Combination Expressions
     4.7     Conditional Expressions
     4.8     table and list Expressions
             _____     ____
           4.8.1 Tables
           4.8.2 Lists
     4.9     selecton Expressions
             ________

BCPL Reference Manual                               Page   4
Introduction


5.  Commands
     5.1     Simple Assignment Commands
     5.2     Assignment Commands
     5.3     Routine Calls
     5.4     Labelled Commands
     5.5     goto Commands
             ____
     5.6     if Commands
             __
     5.7     unless Commands
             ______
     5.8     while Commands
             _____
     5.9     until Commands
             _____
     5.10    test Commands
             ____
     5.11    Repeated Commands
     5.12    for Commands
             ___
     5.13    switchon Commands
             ________
     5.14    loop, break, and endcase Commands
             ____  _____      _______
     5.15    finish Commands
             ______
     5.16    return Commands
             ______
     5.17    resultis Commands
             ________
     5.18    Sections and Blocks

6.  Definitions
     6.1     Scope Rules
     6.2     Space Allocation and Extent of Variables
     6.3     Externals
     6.4     Globals
     6.5     Statics
     6.6     Manifests
     6.7     Simple Variables
     6.8     Vectors
     6.9     Functions
     6.10    Routines
     6.11    Simultaneous Definitions

7.  Structures
     7.1     Introduction
     7.2     Syntax
     7.3     Semantics
     7.4     Examples

                         REFERENCES

BCPL Reference Manual                               Page   5
Introduction


                         APPENDICES
A. BCPL Characteristics
      A.1 Reserved Words and Symbols
      A.2 The TENEX BCPL Character Set
      A.3 The BCPL Pre-processor: 
            Comments
            Semi-colon and DO Insertion
            PSEUDO Commands (e.g. GET)
      A.4 Operator Precedence
      A.5 Subtle Features

B. Usage of TENEX BCPL
     B.1 Typical source file organization
     B.2 Using the compiler
     B.3 Constructing a BCPL main program
     B.4 Routine and Function linkage conventions
     B.5 Utility programs
          B.5.1 FMT.SAV
          B.5.2 OCODE.SAV
          B.5.3 PSYMB.SAV
          B.5.4 PSAVE.SAV
          B.5.5 CONC.SAV
     B.6 A Complete, Realistic, Working Example Program

C. Functions, Routines, and Special Static Variables in the TENEX BCPL
 Library
     C.1 I/O
          C.1.1 I/O Streams
          C.1.2 Character, Word, and String I/O
          C.1.3 Integer and Floating Point I/O
          C.1.4 ARPANET Interface
          C.1.5 Formatted Output
     C.2 JSYS Interface
     C.3 Byte Manipulation
     C.4 String Manipulation and Number Conversion
     C.5 Error Handling
     C.6 Arrays
     C.7 Hash-coded Dictionary
     C.8 "Heap" Free Storage
     C.9 PSI Handling
     C.10 Miscellany

D. Debugging

BCPL Reference Manual                               Page   6
Introduction


1.  Acknowledgements
    ________________

     BCPL was originally designed and implemented by  Martin  Richards
at  MIT  Project  MAC.   Many  people  have  since  contributed to the
development  of  the  language,  compiler,  utilities,  and  debugging
system,  as  represented  in  the TENEX BCPL system.  The language and
compiler were extended  to  include  structures,  symbol  tables,  and
various new language constructs by the group at MIT Lincoln Laboratory
on the TX-2 computer, led by Art Evans.  Carl Ellison  (University  of
Utah  Computer  Science  Department)  built a TENEX BCPL bootstrap and
brought an early version of the Lincoln compiler to Utah-TENEX through
the  ARPANET.   He  also built the first TENEX BCPL I/O library.  Paul
Rovner brought the Utah system to BBN-TENEX through the ARPANET,  then
used  it  to  bootstrap  an  improved  version  of Lincoln's compiler.
Victor Miller (BBN) helped to upgrade Ellison's code generators.   The
present  TENEX  BCPL  system includes several packages of routines and
functions, and several utility programs that were brought from Lincoln
and  modified  for  use on TENEX by Paul Rovner.  Other utilities were
contributed by Jerry Wolf, Ray Tomlinson, and Richard Schwartz at BBN.
The TENEX BCPL debugger was designed and implemented by Jim Miller and
Paul Rovner, with help by John Sybalsky.   And  Gail  Hedtler  of  the
TENEX  group at BBN spent many hours puzzling through pencil scratched
versions of this manual as she converted it to RUNOFF format and keyed
it in.

BCPL Reference Manual                               Page   7
Introduction


2.  Introduction
    ____________

     This document is designed to  be  an  introduction  to  the  BCPL
programming  language,  a reference manual for it, and a user's manual
for the BCPL programming system on TENEX.  The description here of the
BCPL   programming   language   is   independent   of  any  particular
implementation;  features  of  the  language  which  depend   on   the
implementation  (like  the  number  of bits in a word) are pointed out
(where appropriate) in the text.

     The reserved words and symbols used in the language  descriptions
(and  in  the  examples) are taken from the reserved words and symbols
for TENEX BCPL.  By convention, reserved words are composed  of  lower
case characters only.  Reserved words are underlined in this manual.

     Section 3 (below) is an introduction to the  philosophy  of  BCPL
and  to  the  key  elements  of  the language.  The next four sections
describe in detail the form and meaning of the language constructs for
expressions, commands, definitions, and structures, respectively.  The
appendices describe the TENEX BCPL programming system and how  to  use
it.   Also  in  the  appendices  are  the  list  of reserved words and
symbols, a description of the features of  the  pre-processor,  and  a
description  of  the inevitable (but very few!) glitches out for which
the new user should look.  Attached as addenda to  this  document  are
the  figures  referred  to  in  the text, and a chart of BCPL operator
precedence relations.

     The BCPL convention for program comments is that two adjacent "/"
characters  anywhere in the program identify the remainder of the line
as arbitrary text, to be skipped over and ignored by the compiler.

     The syntactic notation used is basically BNF with  the  following
extensions:

          (1) The symbols N, E, D, and C are  used  as  shorthand  for
          <name>, <expression>, <definition>, and <command>.

          (2) The metalinguistic brackets '<' and '>'  may  be  nested
          and  thus  used  to group together more than one constituent
          sequence  (which  may  contain  alternatives).   An  integer
          subscript  may be attached to the metalinguistic bracket '>'
          and used to specify repetition.  If it  is  the  integer  n,
          then  the  sequence  within the brackets must be repeated at
          least n times; if the integer is followed by a  minus  sign,
          then  the sequence may be repeated at most n times or it may
          be absent.

BCPL Reference Manual                               Page   8
Concepts


3.  Fundamental Concepts of BCPL
    ___________ ________ __ ____


     3.1  The Object Machine
          ___ ______ _______

     BCPL has a simple underlying semantic structure  which  is  built
around  an idealized object machine.  This method of design was chosen
in order to make BCPL easy to  define  accurately  and  to  facilitate
machine  independence,  which  is  one  of the fundamental aims of the
language.

     The most important feature of the object machine  is  its  memory
store.  This is represented diagrammatically in Figure 1.  It consists
of a set of numbered boxes (called "storage cells") arranged  so  that
the  numbers  labelling adjacent cells differ by one.  As will be seen
later, this property is important.

     Each storage cell holds a binary pattern called a  "Value".   All
storage  cells  are  of  the  same  size and the length of Values is a
constant of the implementation which is  usually  between  16  and  36
bits.   A  Value  is  the only kind of object which can be manipulated
directly in BCPL.  Every variable and expression in the language  will
always have a Value.

     Values are used by the programmer to model  abstract  objects  of
many  different  kinds  such  as  truth  values,  strings, arrays, and
functions.  There are a large number of  basic  operations  on  Values
which  have  been  provided  in order to help the programmer model the
transformation of his abstract objects.  In particular, there are  the
usual  arithmetic  operations.   These may be understood as operations
which interpret  their  operands  as  integers,  perform  the  integer
arithmetic   and   convert  the  result  back  into  the  Value  form;
alternatively, one may think of them as operations which work directly
on  bit  patterns  and  just  happen  to  be  useful  for representing
integers.  This latter approach is  closer  to  the  BCPL  philosophy.
Although the BCPL programmer has direct access to the bits of a Value,
the details of the binary representation used  to  represent  integers
are  not  defined  and  he  would be losing machine independence if he
performed non-numerical operations on Values  he  knows  to  represent
integers.

     An operation of fundamental importance in the object  machine  is
that  of  indirection.   This  operation  has  one  operand  which  is
interpreted as an integer and it locates the  storage  cell  which  is
labelled  by  this integer.  This operation is assumed to be efficient
and, as will be seen later, the programmer may invoke it  from  within
BCPL using the rv operator.
               __



BCPL Reference Manual                               Page   9
Concepts


     3.2  Names, Variables, and Manifest Constants
          ______ __________ ___ ________ _________

     A BCPL name (see 4.1.4) is associated either with a storage cell,
in  which  case  the  name represents a "variable", or with a constant
Value, in which case the name represents a "manifest  constant".   The
Value  of a BCPL variable is the Value contained in the cell; the term
"variable" is used since this Value may be changed  by  an  assignment
command  during  execution.   Variables  are introduced by let and and
                                                           ___     ___
declarations, the for command, formal parameter lists, and the  static
                  ___                                           ______
declaration.  From the point of view of how storage cells are assigned
to  variables,  there  are  two  kinds  of  variables:  "dynamic"  and
"static".  A Dynamic variable is assigned a storage cell each time the
program in which  it  is  defined  is  executed.   When  this  program
finishes,  the storage cell is reclaimed for use by other programs.  A
static variable is assigned its storage cell by the  compiler,  before
program  execution.  This storage cell is uniquely associated with the
static variable, and this association does not change  during  program
execution.

     A "manifest constant" is  a  name  which  is  associated  with  a
constant  Value;  this  association  takes  place  at compile time and
remains  the  same  throughout  execution.   Manifest  constants   are
introduced  by  the  manifest declaration and by the label declaration
                     ________
(see 5.4).  There are many situations where manifest constants can  be
used  to  improve  readability  at no cost in run time efficiency, for
example:

          manifest { PI : 3.1415926⎇
          ________


     3.3  Addresses
          _________

     As previously  stated,  each  storage  cell  is  labelled  by  an
integer;  this  integer  is  called  the Address of the cell.  Since a
variable is associated with a storage cell, it must also be associated
with   an   Address   and   one  can  usefully  represent  a  variable
diagrammatically as in Figure 2.

     Within the machine an Address is  represented  by  a  binary  bit
pattern  of  the same size as a Value, and so a Value can represent an
Address directly.  Thus, a variable  may  have  the  Address  of  some
storage  cell  as its Value.  The programmer might think of this Value
as a "pointer" to the storage cell.

BCPL Reference Manual                               Page  10
Concepts


     3.4  Simple Assignment
          ______ __________

     The syntactic form of a simple assignment command is:

          E1 ← E2

where  E1  is  either  a  variable  or  some  other  expression  which
represents  a  storage  cell  (for  example, see 4.1.10), and E2 is an
arbitrary expression.  Loosely, the meaning of the  assignment  is  to
evaluate E2 and store its Value in the storage cell referred to by E1.
This process is shown diagrammatically in Figure 3.

Example:

          X ← 7


     3.5 The lv Operator
         ___ __ ________

     As previously stated, an Address is represented by a  binary  bit
pattern  which  is the same size as a Value.  The lv operator provides
                                                  __
the facility of accessing the Address of a storage cell.

     The syntactic form of an lv expression is:
                              __

          lv E
          __

where E is an expression which represents a storage cell.  The process
of  evaluation  for  the  lv  expression  is shown diagrammatically in
                          __
Figure 4.  The Value of the lv Expression is the Address of the  given
                            __
storage cell.


     3.6  The rv Operator
          ___ __ ________

     The rv operator is  important  in  BCPL  since  it  provides  the
         __
underlying  mechanism for manipulating data structures; it operates to
yield the storage cell whose address is the Value of the operand.

     The syntactic form of an rv expressions is as follows:
                              __

          rv E
          __

and its process of evaluation is shown diagrammatically in  Figure  5.
Note that rv (lv E) is identical to E (but only if E has an Address).
          __  __

BCPL Reference Manual                               Page  11
Concepts


     3.7  Data Structures
          ____ __________

     The considerable power and usefulness of the rv operator  can  be
                                                  __
seen by considering Figure 6.

     The diagram shows a possible interpretation of the Value  of  the
expression

          V + 3.

Some adjacent storage cells are shown; the  top  one  has  an  Address
which is the same bit pattern as the Value of V.  One will recall that
an Address is really an integer and that Addresses of  adjacent  cells
differ  by  one, and thus the Value of (V + 3) is the same bit pattern
as the Address of the  bottom  box  shown  in  the  diagram.   If  the
operator rv is applied to (V + 3), then the contents of that cell will
         __
be accessed.  Thus the expression:

          rv (V + i)
          __

acts very like a vector subscripting operation,  since,  as  i  varies
from zero to three, the expression refers to the different elements of
the set of four cells pointed to by V.  V can be  thought  of  as  the
vector  and i as the integer subscript.  The notion of a "vector" is a
central one in BCPL.  A Value which  is  used  to  address  the  first
storage  cell in a block of adjacent storage cells is said to define a
"vector" of storage cells.

     Since  this  facility  is  so  useful,  the  following  syntactic
sugaring is provided:

          E1!E2 or E1|E2 is equivalent to rv (E1 + E2)
                                          __

A simple example of its use is the following command:

          V|(i + 1) ← V|i + U|i

     One can see how the rv operation can be used in  data  structures
                         __
by considering the following:

          V|3 = rv (V + 3)     by definition
                __
              = rv (3 + v)     since + is commutative
                __
              = 3|V

Thus V|3 and 3|V are semantically equivalent; however, it is useful to
attach  different  interpretations  to  them.  We have already seen an
interpretation of V|3 so let us consider the other expression.  If  we
rewrite   3|V  as  Xpart|V  where  Xpart  has  value  3,  we  can  now
conveniently think of this expression as a selector (Xpart) applied to
a structure (V).  

     By letting the elements of structures themselves be structures it
is  possible  to  construct  compound  data  structures  of  arbitrary

BCPL Reference Manual                               Page  12
Concepts


complexity.  Figure 7 shows  a  structure  composed  of  integers  and
pointers.


     3.8  Data Types
          ____ _____

     The unusual way in which BCPL treats data types is fundamental to
its design, and thus some discussion of types is in order here.  It is
useful to introduce two classes:
          (a)  conceptual types
          (b)  internal types

     The conceptual type of an expression  is  the  kind  of  abstract
object  the  programmer  had in mind when he wrote the expression.  It
might be, for instance, a time in milliseconds, a weight in  grams,  a
function  to  transform feet per second to miles per hour, or it might
be a data structure representing a parse  tree.   It  is,  of  course,
impossible  to  enumerate all the possible conceptual types, and it is
equally impossible to provide for all of them  individually  within  a
programming language.  One standard practice when designing a language
is to select from the conceptual types some basic ones and  provide  a
suitable  internal  representation  together  with  an adequate set of
basic operations.  The term "internal type" refers to any one of these
basic  types;  the  intent  is  that  all  the conceptual types can be
modelled effectively using the internal types.  A few of the  internal
types provided in a typical language, such as CPL, are listed below:
               real
               ____
               integer
               _______
               label
               _____
               integer function
               _______ ________
               (real, boolean) vector
                ____  _______  ______

     Much of the flavor of BCPL is the result of the conscious  design
decision  to  provide  only  one internal type, namely, the binary bit
pattern (or Value).  In order to allow the  programmer  to  model  any
conceptual  type,  a large set of useful primitive operations has been
provided.  For instance, the ordinary arithmetic operators + - * and /
have  been  defined  for  Values in such a way as to model the integer
operations directly.  The six standard relational operators have  been
defined  and  a  complete set of bit manipulating operations provided.
All the operations provided are uniformly efficient and they have  not
been "over-defined".  For instance, the effect of adding a number to a
label, or a vector to a function is not  defined  even  though  it  is
possible for a programmer to cause it to take place.

BCPL Reference Manual                               Page  13
Concepts


     The most important effects of designing BCPL in this way  can  be
summarized as follows:

     1.   There is no need for  type  declarations  in  the  language,
          since  there  is  only  one type of variable.  This helps to
          make programs concise and also  simplifies  such  linguistic
          problems  as  the handling of actual parameters and separate
          compilation.

     2.   BCPL has much of the power of a  language  with  dynamically
          varying  types  and  yet  it  retains  the  efficiency  of a
          language (like FORTRAN) with manifest  types;  although  the
          internal  type  of  an  expression  is  always  known by the
          compiler, its conceptual type can never be, and, indeed,  it
          may depend on the values of variables within the expression.
          For instance, the conceptual type of V|i may depend  on  the
          value  of  i.   One  should note that, in languages (such as
          ALGOL and CPL) where the elements of vectors must  all  have
          the  same  type,  one  needs some other linguistic device in
          order to handle more general data structures.

     3.   Since there is only one  internal  type,  there  can  be  no
          automatic   type  checking  and  it  is  possible  to  write
          nonsensical  programs  which  the  compiler  will  translate
          without  complaint.   This  slight  disadvantage  is  easily
          outweighed by the simplicity, power and efficiency that this
          treatment of types makes possible.  Interpretations:

               (a)  The Value of a variable of conceptual type  vector
          is a storage cell-sized bit pattern (36 bits for TENEX BCPL)
          which is interpreted as the Address of the zeroth element of
          the  vector.   I.e., rv v and v|0 represent the same storage
                               __
          cell.

               (b)  The Address of the nth element of a vector  v  may
          be  obtained  by  adding  the integer n to v; thus lv v|n is
                                                             __
          equal to v + n.

               (c) The Value of a label is a bit pattern  representing
          the program position of the labelled command.

               (d) The Value of a function or routine is a bit pattern
          representing  the program position of the entry point of the
          function or routine (see 6.9 and 6.10).

BCPL Reference Manual                               Page  14
Expressions


4.  Expressions
    ___________

     All BCPL expressions are described in  this  section.   They  are
presented  in  syntactic  classes  in  the order of decreasing binding
power.  The term "binding power" refers to the strength with which  an
operator   binds  its  arguments.   For  example,  the  multiplication
operator "binds  more  strongly"  than  the  addition  operator.   The
expression
          E1*E2+E3
means
          (E1*E2)+E3
not
          E1*(E2+E3)

A concise presentation of the  relative  binding  power  of  the  BCPL
operators is given in Appendix A.4.

     4.1  Primary expressions
          _______ ___________

     These are the most binding and most primitive expressions.   They
are:
          numeric constants, character  constants,  string  constants,
          names, Boolean constants, nil, bracketted expressions, valof
                                    ___                          _____
          expressions, function applications, vector applications,  lv
                                                                    __
          expressions,   rv   expressions,   half   and  quarter  word
                         __
          extraction expressions, and structure references.

     4.1.1  Numerical Constants
            _________ _________

     Syntactic form:
                    <decimal digit>1
                 or #<octal digit>1
                 or <decimal digit>1.<decimal digit>1

     Semantics:
                    The sequence of digits is interpreted as a decimal
                    integer  in  the  first case, as a right justified
                    octal number in the  second,  and  as  a  floating
                    point  number  in the third.  In TENEX BCPL, other
                    formats for floating point constants are  allowed,
                    per the FLIN JSYS [4].

BCPL Reference Manual                               Page  15
Expressions


     4.1.2  Character Constants
            _________ _________

     Syntactic form:
                    $<character>

     Semantics:
                    A  character  constant   has   an   implementation
                    dependent   Value   which   is   the  bit  pattern
                    representation of the  character;  this  is  right
                    justified  and  the  remainder  of the bits in the
                    Value are zeros.  See appendix A.2 for the list of
                    TENEX  characters  and a description of the escape
                    conventions for special characters.
                    TENEX example:

                         $a = #141 (ASCII value)

     4.1.3  String Constants
            ______ _________

     Syntactic form:
                    "<character>1"
                 or '<character>1'

     Example:
                    "Abc*n"

     Semantics:
                    A string of characters delimited by " represents a
                    BCPL   string   constant.    On   TENEX,  this  is
                    represented as a vector, with  the  characters  in
                    successive words, packed four to a word, from left
                    to right.  The leftmost quarter of the zeroth word
                    contains  the  number of characters in the string.
                    This is limited  to  511  (9  bits!).   The  first
                    character is stored in the quarter which is second
                    from the left in the zeroth word.  Extra  quarters
                    in  the  last word of a string will be padded with
                    zeros.

                    A string of characters  delimited  by  '  is  also
                    represented   as   a   BCPL   vector:  the  string
                    characters are packed in successive words  of  the
                    vector, in ASCIZ string format.
                    Note  that  the  escape  conventions  for  special
                    characters also hold in string constants.

BCPL Reference Manual                               Page  16
Expressions


     4.1.4  Names
            _____

     Syntactic form: 
                    A name is a sequence of one or more (less than 24)
                    characters  from  a restricted alphabet called the
                    name   character   alphabet.     The    particular
                    characters  in  this  alphabet  and  the rules for
                    recognizing the  starts  and  ends  of  names  are
                    implementation dependent.

                    The TENEX name  character  alphabet  contains  the
                    letters  A....Z  and a....z and the digits 0....9.
                    A name must start with a letter.

     Semantics:
                    Two names are equal if they have the same sequence
                    of name alphabet characters.  A name may always be
                    evaluated to yield  a  Value.   If  the  name  was
                    declared to be a label or a manifest constant (see
                    section 6.6) then the Value will be  the  same  on
                    every evaluation.  If the name was declared in any
                    other way then it is a variable and its Value  may
                    be changed dynamically by an assignment command.

     4.1.5  Boolean Constants
            _______ _________

     Syntactic form:
                    true or false
                    ____    _____
     Semantics:
                    The actual bit patterns which are  the  Values  of
                    true  and  false are implementation dependent.  On
                    ____       _____
                    TENEX, the Value of true is a bit pattern entirely
                                        ____
                    composed  of  ones.   The  Value of false is zero.
                                                        _____
                    Note that true = not false
                              ____   ___ _____


BCPL Reference Manual                               Page  17
Expressions


     4.1.6  Unspecified Initial Value
            ___________ _______ _____

     Syntactic form:
                    nil
                    ___

     Example:
                    let x ← nil
                    ___     ___

     Semantics:
                    The Value of nil is undefined.  Its purpose is  to
                                 ___
                    allow the user to not specify an initial value for
                    a newly defined cell.  In the example, the dynamic
                    variable  x  is  defined without an initial Value.
                    nil may also be used in  formal  parameter  lists,
                    ___
                    actual   parameter   lists,  subword  expressions,
                    tables, lists and static declarations.

     4.1.7  Parenthesized Expressions
            _____________ ___________

     Syntactic form:
                    (E)

     Semantics:
                    Any expression may  be  enclosed  in  parentheses;
                    this is used to specify grouping.

     4.1.8  valof Expressions
            _____ ___________

     Syntactic form:
                    valof <section or block>
                    _____

     Semantics:
                    A valof expression is evaluated by  executing  the
                      _____
                    section  or  block  (see  5.18)  until  a resultis
                                                              ________
                    statement is encountered (see 5.17), which  causes
                    execution  of  the section or block to cease.  The
                    Value of the valof expression is the Value of  the
                                 _____
                    expression in the resultis command.
                                      ________
     Example:
               char←valof
                    _____
                     { WriteS("Character:")   //Ask for a character
                       resultis Readch()   //read and return it
                     ⎇

BCPL Reference Manual                               Page  18
Expressions


     4.1.9  Function Applications
            ________ ____________

     Syntactic form:
                    E1 (E2, E2, ...  En)
                    where  E1  is  one  of  the  primary   expressions
                    introduced above.

     Semantics:
                    The   function   application   is   evaluated   by
                    evaluating  the  expressions  E1,  E2, ...  En and
                    assigning the Values of E2 ...  En  to  the  first
                    n-1  formal parameters of the function whose Value
                    is  the  Value  of  E1.   This  function  is  then
                    entered.   The  result  of  the application is the
                    Value of the expression in the function definition
                    (see section 6.9).

     4.1.10  Vector Applications (i.e.  vector subscripting)
             ______ ____________

     Syntactic form:
                    E1|E2
                 or E1!E2
                    where both E1 and E2 are primary expressions.

     Semantics:
                    A Value of conceptual type "vector" is the Address
                    of  the zeroth storage cell in a block of adjacent
                    storage cells.  A vector application represents  a
                    storage cell.  To obtain the Address of this cell,
                    E1 and E2 are evaluated and summed.  The Value  of
                    the  vector application expression is the Value in
                    this cell.  E1 is often interpreted as  the  Value
                    of  a  vector  and  E2 as the subscript.  From the
                    definition of lv expressions (section 4.1.11), the
                                  __
                    Address  of an element of a vector may be obtained
                    by evaluating the expression 

                              lv E1|E2
                              __

                    The  representations  of  Vectors,  Addresses  and
                    integers  is such that the following relations are
                    true:

                              E1|E2 = rv (E1 + E2)
                                      __

                              lv E1|E2 = E1 + E2
                              __

                    Note that
                              E1|E2|E3|E4
                    is calculated as
                              (((E1|E2)|E3 )|E4)
                    also,
                              E1|E2 = E2|E1

BCPL Reference Manual                               Page  19
Expressions


                    Function applications are more binding than vector
                    applications, i.e., 

                              y|f(x) means y|(f(x)).

     4.1.11  lv Expressions
             __ ___________

     Syntactic form:
                    lv E
                    __
                    where E is a primary expression

     Semantics:
                    The Address of an expression  which  represents  a
                    storage  cell  may  be  obtained  by  applying the
                    operator lv; it is only meaningful to apply lv  to
                             __                                 __
                    a  vector  application,  an  rv  expression, or an
                                                 __
                    identifier which is not a manifest  constant.   lv
                                                                    __
                    expressions   are   less   binding   than   vector
                    applications, e.g., 

                              (lv V|X) is (lv (V|X))
                               __          __

                    The Value of an lv expression is  the  Address  of
                                    __
                    the  specified storage cell.  Examples of operands
                    to the lv operator:
                           __

                         (a)  A vector application.
                         The result is  the  Address  of  the  element
                         referenced (see section 4.1.10).

                         (b)  An rv expression.
                                 __
                         The result is the Value of the operand of rv.
                                                                   __

                         (c)  A name.
                         The result is the Address of the storage cell
                         which is associated with the given name (this
                         name must not represent a manifest constant).

BCPL Reference Manual                               Page  20
Expressions


     4.1.12  rv Expressions
             __ ___________

     Syntactic form:
                    rv E
                    __
                    where E is a primary expression.

     Semantics:
                    An rv expression represents a storage  cell  whose
                       __
                    Address   is  the  Value  of  the  operand  (TENEX
                    implementation: The full width of  E  is  used  to
                    compute   the   Address   of   the  storage  cell,
                    particularly  the  indirect  and  index   register
                    fields[CAVEAT!!]).    rv   expressions   are  less
                                          __
                    binding than vector applications.

     Examples:

                              rv #100000 ← 7
                              __
                    stores the Value 7 into  the  storage  cell  whose
                    Address is 100000 (octal).

                              rv v ← 1 + rv v
                              __         __

                    increments the Value of  the  storage  cell  whose
                    address is the Value of v.

                              v|0 ← 1 + v|0

                    same as previous example.  

     4.1.13  Half-word Extraction Expressions
             _________ __________ ___________

     Syntactic form:
                    lh E
                    __
                 or rh E
                    __
                 or lhz E
                    ___
                 or rhz E
                    ___
                    where E is a primary expression.

     Semantics:
                    The Value of a half-word extraction expression  is
                    the  storage  cell-sized  bit  pattern whose right
                    half is the right half (for rh and  rhz)  or  left
                                                __      ___
                    half (for lh and lhz) of E, and whose left half is
                              __     ___
                    all zeros (if lhz or rhz) or sign extended (if  lh
                                  ___    ___                        __
                    or  rh).   The  lh  and  rh  half-word  extraction
                        __          __       __
                    expressons may appear  on  the  left  side  of  an
                    assignment statement (see section 5.1).  Half word
                    extraction  expressions  are  less  binding   than
                    vector applications.

BCPL Reference Manual                               Page  21
Expressions


     4.1.14  Quarter-word Extraction Expressions
             ____________ __________ ___________

     Syntactic form:
                    q1 E
                    __
                 or q2 E
                    __
                 or q3 E
                    __
                 or q4 E
                    __
                 or q1z E
                    ___
                 or q2z E
                    ___
                 or q3z E
                    ___
                 or q4z E
                    ___
                    where E is a primary expression.

     Semantics:
                    The Value of a quarter-word extraction  expression
                    is   the  storage  cell-sized  bit  pattern  whose
                    rightmost quarter is the indicated  quarter  of  E
                    (q1   indicates  the  rightmost  quarter,  q4  the
                     __                                        __
                    leftmost), and whose remainder is  zero  (if  q1z,
                                                                  ___
                    q2z,  q3z,  or  q4z), or sign-extended (if q1, q2,
                    ___   ___       ___                        __  __
                    q3, or q4).  The q1, q2, q3, and q4  quarter  word
                    __     __        __  __  __      __
                    extraction expressions may appear on the left side
                    of an assignment statement (see section 5.1).  The
                    binding   power   of   quarter   word   extraction
                    expressions is the  same  as  that  of  half  word
                    extraction expressions.

     4.1.15  Structure References
             _________ __________

      Structure references are primary expressions.  See section 7.

BCPL Reference Manual                               Page  22
Expressions


     4.2  Arithmetic Expressions
          __________ ___________

     These expressions provide the standard integer and floating point
operations   of  multiplication,  division,  remainder,  addition  and
subtraction.  They are less binding than the primary expressions.

     Syntactic form:
                    E1 * E2
                 or E1 / E2
                 or E1 rem E2
                       ___
                 or E1 + E2
                 or E1 - E2
                 or E1 %* E2
                 or E1 %/ E2
                 or E1 %+ E2
                 or E1 %- E2
                 or -E1
                 or +E1

                    The operators %* %/ * / and rem are  more  binding
                                                ___
                    than  %+  %-  +  and  - and associate to the right
                    [i.e.  E1/E2/E3=E1/(E2/E3)].  The operators %+  %-
                    + and - associate to the left
                    [i.e.  E1-E2-E3=(E1-E2)-E3].

     Semantics:
                    The integer  operators  interpret  the  Values  of
                    their   operands  as  signed  integers  and  yield
                    integer results.  The operator *  denotes  integer
                    multiplication.   The  division  operator / yields
                    the correct result if E1 is divisible by E2; it is
                    otherwise   implementation   dependent   but   the
                    rounding error is never greater than 1.  On TENEX,
                    the  result  is  obtained  by an IDIV instruction,
                    which truncates.   The  operator  rem  yields  the
                                                      ___
                    remainder of 
                    (E1 divided by E2);  its  exact  specification  is
                    implementation dependent.  On TENEX, the result is
                    obtained by the IDIV instruction.  The operators +
                    and  -  denote  integer  addition and subtraction.
                    The four floating point  operators  interpret  the
                    Values of their operands as floating point numbers
                    and  perform  the  indicated  operations.   (Note:
                    Automatic  conversion between integer and floating
                    point numbers does NOT occur in BCPL.  It  is  the
                    user's   responsibility   to   use   the   correct
                    operators).

BCPL Reference Manual                               Page  23
Expressions


     4.3  Relational Expressions
          __________ ___________

     A relational expression takes integer or floating point arguments
and yields a Boolean Value to represent the truth of the relation.

     Syntactic Form:
                    E1 <relop> E2 ...  <relop> En
                    where <relop> ::= eq | ne | ls | gt | ge | le 
                                      __   __   __   __   __   __
                    and n > 1
                    The relational operators are less binding than the
                    arithmetic operators.
                    (NOTE: lt and < are synonyms for ls ; gr and > are
                           __                        __   __
                    synonyms for gt ; = is a synonym for eq).
                                 __                      __

     Semantics:
                    The Value of a relational expression  is  true  if
                                                              ____
                    and only if all the individual relations are true.
                                                                 ____
                    The  order   of   evaluation   is   implementation
                    dependent.    The   Values   of   the  expressions
                    E1 ... En are interpreted as signed  integers  and
                    the   relational   operators   have   their  usual
                    mathematical meanings.   On  TENEX,  the  floating
                    point  number  representation  is  such  that this
                    interpretation is also correct for floating  point
                    relational expressions.  Note that the Value of an
                    expression  such  as  x=true   is   implementation
                                            ____
                    dependent.

     4.4  Shift Expressions
          _____ ___________

     The shift operations allow one to shift a binary bit  pattern  to
the left or right by a specified number of bit positions.

     Syntactic form:
                    E1 lshift E2
                       ______
                 or E1 rshift E2
                       ______
                 or E1 lscale E2
                       ______
                 or E1 rscale E2
                       ______

                    E2 is any primary or arithmetic expression and  E1
                    is  any  shift,  relational, arithmetic or primary
                    expression.  Thus the  shift  operators  are  less
                    binding  than  the  relations on the left and more
                    binding on the right.

BCPL Reference Manual                               Page  24
Expressions


     Semantics:
                    The shift operations are logical  operations;  the
                    scale  operations  are arithmetic operations.  The
                    Value of  E1  is  interpreted  as  a  logical  bit
                    pattern  and that of E2 as an integer.  The result
                    of E1 lshift E2 is the bit  pattern  E1  logically
                          ______
                    shifted to the left by E2 bit positions.  If E2 is
                    negative, shifting occurs to the right.  E1 rshift
                                                                ______
                    E2  is  as  for  lshift but shifts in the opposite
                                     ______
                    direction.  For the shift operators,  vacated  bit
                    positions  are filled with zeros and the result is
                    zero if E2 is greater than the number of bits in a
                    machine word.  For the scale operators, the result
                    is:
                       E1 times (2 to the power E2).

     4.5  Logical Expressions
          _______ ___________

     These expressions  allow  one  to  manipulate  bits  of  a  Value
directly.  They can be used in conjunction with the shift operators to
pack and unpack data.  The standard BCPL representations of  true  and
                                                             ____
false  are  chosen  so  that the logical operators may also be used on
_____
Boolean data.
     Syntactic form:
                    } E1 (also not E1)
                               ___
                 or E1 & E2
                 or E1 \ E2
                 or E1 eqv E2
                       ___
                 or E1 neqv E2
                       ____

                    The  not  operator  is  most  binding;  then,   in
                         ___
                    decreasing order of binding power are:

                         &, \, eqv, neqv
                               ___  ____

                    All the logical operators are  less  binding  than
                    the shift operators.

     Semantics:
                    The operands of  all  the  logical  operators  are
                    interpreted  as  binary  bit  patterns of ones and
                    zeros.  The application of the not operator yields
                                                   ___
                    the  logical  negation  of its operand (bit-by-bit
                    complement).  The Value of the application of  any
                    other  logical operator is a bit pattern whose nth
                    bit depends only on the nth bits of  the  operands
                    and can be determined by the following table:


BCPL Reference Manual                               Page  25
Expressions


The Values of                 Operator
the nth bits        &         \         eqv       neqv
                                        ___       ____

both ones           1         1         1         0
both zeros          0         0         1         0
otherwise           0         1         0         1


BCPL Reference Manual                               Page  26
Expressions


     4.6 Half-word Combination Expressions
         _________ ___________ ___________

     Syntactic form:
                    E1,,E2
                    where E1 and E2 may be any logical  expression  or
                    expressions of greater binding power

     Example:
                    E3,, E4 & E5
                    parses as E3,, (E4 & E5)

     Semantics:
                    E1,,E2
                    produces a storage cell-sized Value (36  bits  for
                    TENEX  BCPL)  whose  left  half is the same as the
                    right half of E1, and whose right half is the same
                    as the right half of E2.

     4.7  Conditional Expressions
          ___________ ___________

     A conditional expression allows for conditional evaluation of one
of two expressions.

     Syntactic form:
                    E1 -> E2, E3
                 or E1 => E2, E3
                    where  E1,  E2,  and  E3  may   be   any   subword
                    expressions  or  expressions  of  greater  binding
                    power.  E2 and E3 may, in addition be  conditional
                    expressions.

     Semantics:
                    The Value of the  conditional  expression  is  the
                    Value  of  E2 or E3 depending on whether the Value
                    of E1 represents true or false  respectively.   In
                                     ____    _____
                    either case only one alternative is evaluated.  If
                    the Value of E1 does not represent either true  or
                                                              ____
                    false then the Value of the conditional expression
                    _____
                    is undefined.

BCPL Reference Manual                               Page  27
Expressions


     4.8  table and list Expressions
          _____ ___ ____ ___________

     These represent the two ways of creating initialized vectors: the
table  expression  causes  a  vector  to  be  built and initialized at
_____
compile time in static storage; the list expression causes a vector to
                                    ____
be built and initialized at run time in dynamic storage.

     4.8.1 Tables

     Syntactic form:
                    table E0, E1, ...  En
                    _____
                    where all the expressions are  more  binding  than
                    comma.

     Semantics:
                    A table is a  static  vector  whose  elements  are
                    initialized  prior  to  execution to the Values of
                    the expressions E0 to En; these  expressions  must
                    have Values which can be computed at compile time.
                    The Value of a table is a pointer  to  its  zeroth
                    element.   The  elements  of  a  table may include
                    tables, vectors, or strings.

     Example:
                    static{ x ← table 1,2,3⎇
                    ______      _____

     4.8.2 Lists

     Syntactic form:
                    list E0, E1, ...  En
                    ____
                    The initial values E0, E1,  ...   En  can  be  any
                    expressions.

     Semantics:
                    The expressions are evaluated and  stored  in  the
                    list at the time the list expression is evaluated.
                    The  storage  is  allocated  dynamically  as   for
                    vectors.
                       let L ← list E0, E1, ...  En
                       ___     ____
                    is equivalent to
                       let L ← vec n
                       ___     ___
                       L|0, L|1, ...  L|n ← E0, E1, ...  En

BCPL Reference Manual                               Page  28
Expressions


     4.9  selecton Expressions
          ________ ___________

     Syntactic form:
                    selecton E into { <list of cases> ⎇
                    ________   ____
                    where each "case" in the  <list  of  cases>  is  a
                    label of the form:
                         case <constant>:
                         ____
                    or
                         case <constant1> to <constant2>:
                         ____             __
                    or
                         default:
                         _______

                    followed by an expression to evaluate.

     Semantics:
                    As for the switchon command (section 5.13),  E  is
                               ________
                    evaluated,  and  the indicated "case" is selected.
                    The Value of the selecton expression is the  Value
                                     ________
                    of  the expression which follows the selected case
                                                                  ____
                    label.  If none of the case labels are applicable,
                                           ____
                    the  default label is selected.  The default label
                         _______                         _______
                    should not be omitted.

BCPL Reference Manual                               Page  29
Commands


5.  Commands
    ________

     5.1  Simple Assignment Commands
          ______ __________ ________

     Syntactic form:
                    E1 ← E2
                 or E1 := E2

     Semantics:
                    E1 may either be the name of a variable, a  vector
                    application,   an   rv  expression,  a  half  word
                                        __
                    extraction expression, a quarter  word  extraction
                    expression,  or  a  structure  reference,  and its
                    effect is as follows:

                    (a)  If  E1  is  the  name  of  a  variable:   The
                    assignment replaces the Value of the variable with
                    the Value of E2.

                    (b)  If E1 is a vector application: The  Value  of
                    the storage cell referenced by E1 is changed to be
                    the Value of E2.

                    (c)  If  E1  is   an   rv   expression   (indirect
                                           __
                    addressing):

                    the Value of the operand of rv is  interpreted  as
                                                __
                    an  Address; the Value of E2 then is stored in the
                    storage cell having this Address.

                    (d)  If E1 is a half word expression (only rh  and
                                                               __
                    lh are allowed):
                    __

                              rh E3 ← E4
                              __
                        is syntactic sugar for
                              E3 ← lh E3,, E4
                                   __

                    and
                              lh E3 ← E4
                              __
                        is syntactic sugar for
                              E3 ← E4,, E3

                    (See section 4.6)

                    (e)  If E1 is a quarter word extraction expression
                    (only q1, q2, q3, and q4 are allowed), 
                          __  __  __      __
                              q2 E3 ← E4
                              __
                    causes quarter 2 of E3 to be replaced by quarter 1
                    of  E4.  Quarters are numbered from right to left.
                    See section 4.1.14.

                    (f)  For assignment to structure  references,  see
                    section 7.

BCPL Reference Manual                               Page  30
Commands


     5.2  Assignment Commands
          __________ ________

     Syntactic form:
                    L1, L2, ...  Ln ← R1, R2, ...  Rn

     Semantics:
                    The semantics of the assignment command is defined
                    in  terms  of  the  simple assignment command; the
                    command given above is semantically equivalent  to
                    the  following  sequence, except that the order in
                    which the  simple  assignments  are  done  is  not
                    specified.
                         L1 ← R1
                         L2 ← R2
                         ...
                         Ln ← Rn

     5.3  Routine Calls
          _______ _____

     Syntactic form:
                    E1 (E2, E3, ...  En)

                    where E1 is a name or a parenthesized expression.

     Semantics:
                    The above command is  executed  by  assigning  the
                    Values  of  E2,  E3,  ...   En  to the first n - 1
                    formal parameters of the routine  whose  Value  is
                    the  Value  of  E1;  this routine is then entered.
                    The execution of this command is complete when the
                    execution of the routine body is complete (see 6.9
                    and 6.10).

     5.4  Labelled Commands
          ________ ________

     Syntactic form:
                    N: C 

                    where N is a name.

     Semantics:
                    This  declares  a  manifest  constant   which   is
                    associated with name N; its scope (see 6.1) is the
                    smallest textually enclosing routine  or  function
                    body  (see  6.9  and 6.10) or block (see 5.18) and
                    its  Value  is  a  bit  pattern  representing  the
                    program positon of the command C.

BCPL Reference Manual                               Page  31
Commands


     5.5  goto Commands
          ____ ________

     Syntactic form:
                    goto E
                    ____

     Semantics:
                    E is evaluated to yield a Value, then execution is
                    resumed  at the statement whose label has the same
                    Value.

     5.6  if Commands
          __ ________

     Syntactic form:
                    if E do C
                    __   __
                 also:

                    if E then C
                    __   ____

     Semantics:
                    The Value of E is interpreted as a Boolean  Value.
                    See   section  4.1.5  for  the  representation  of
                    Boolean Values.  If E is true, C is executed.   If
                    E  is false, C is not executed.  If the Value of E
                    represents neither true nor false then the  effect
                    is implementation dependent.  If E is evaluable at
                    compile time, then C is compiled without  any  run
                    time  check of E if E is true; no code is compiled
                                             ____
                    if E is false.  Similar  appropriate  compile-time
                            _____
                    analysis is done for other commands.

     5.7  unless Commands
          ______ ________

     Syntactic form:
                    unless E do C
                    ______   __
     Semantics:
                    For a boolean  expression  E,  this  statement  is
                    exactly equivalent to the following:

                         if not (E) do C
                         __ ___     __

     5.8  while Commands
          _____ ________

     Syntactic form:
                    while E do C
                    _____   __
     Semantics:
                    This is equivalent to the following sequence:

                       goto L
                       ____
                    M: C
                    L: if E then goto M
                       __   ____ ____

                    where  L  and  M  represent  internally  generated
                    names.

BCPL Reference Manual                               Page  32
Commands


     5.9  until Commands
          _____ ________

     Syntactic form:
                    until E do C
                    _____   __

     Semantics:
                    This statement is equivalent to:

                       while not (E) do C
                       _____ ___     __

     5.10  test Commands
           ____ ________

     Syntactic form:
                    test E then C1 or C2
                    ____   ____    __
                 also:

                    test E ifso C1 ifnot C2
                    ____   ____    _____
                 also:

                    test E ifnot C2 ifso C1
                    ____   _____    ____

     Semantics:
                    This statement  is  equivalent  to  the  following
                    sequence:

                        if not (E) goto L
                        __ ___     ____
                        C1
                        goto M
                        ____
                    L:  C2
                    M:

                    where  L  and  M  represent  internally  generated
                    names.

     5.11  Repeated Commands
           ________ ________

     Syntactic form:
                    C repeat 
                      ______
                 or

                    C repeatwhile E 
                      ___________
                 or 

                    C repeatuntil E
                      ___________

                    Where C is any command other than an  if,  unless,
                                                          __   ______
                    until, while, test, or for command.
                    _____  _____  ____     ___

     Semantics:
                    C repeat is equivalent to:
                      ______

                    L: C
                       goto L
                       ____

BCPL Reference Manual                               Page  33
Commands


                    C repeatwhile E is equivalent to:
                      ___________

                    L: C
                       if E then goto L
                       __   ____ ____

                    C repeatuntil E is equivalent to:
                      ___________

                    L: C
                       if not (E) then goto L
                       __ ___     ____ ____

                    where L represents an internally generated name.

                    the repeatwhile command  differs  from  the  while
                        ___________                              _____
                    command  in  that  the  repeatwhile  loop  test is
                                            ___________
                    performed after executing  the  body  of  code  at
                    least  once.   The  same  relation  exists between
                    repeatuntil and until.
                    ___________     _____

     5.12  for Commands
           ___ ________

     Syntactic form:
                    for N ← E1 to E2 do C
                    ___        __    __
                 also:

                    for N ← E1 by E3 to E2 do C
                    ___        __    __    __
                 also:

                    for N ← E1 to E2 by E3 do C
                    ___        __    __    __

                 where N is a name.  NOTE:  step  may  be  used  as  a
                                            ____
                    synonym for by.
                                __

     Semantics:
                    The above statement is equivalent to:

                    { let N ← E1
                      ___
                      let END ← E2
                      ___
                      until N gr END do
                      _____   __     __
                      { C
                      N ← N + E3 ⎇
                    ⎇

                    "by E3" or "step E3" is optional; the increment is
                     __         ____
                    assumed  to be 1 if not specified.  END represents
                    an internally generated name.  If  specified,  the
                    expression  E3  must be evaluable at compile time.
                    Note that the for command  is  an  implicit  block
                                  ___
                    (see 5.18 and 6.1)


BCPL Reference Manual                               Page  34
Commands


     5.13  switchon Commands
           ________ ________

     Syntactic form:
                    switchon E into { <list of cases> ⎇
                    ________   ____

                    where each "case" in the  <list  of  cases>  is  a
                    "case  label"  followed by a sequence of commands.
                    A "case label" has the form:

                       case <constant>:
                       ____

                    or

                       case <constant1> to <constant2>:
                       ____             __

                    or

                       default:
                       _______

                    NOTE: If you want to inject a declaration into the
                    sequence  of  commands  in  a  "case", then make a
                    block (see 5.18) out of the  declaration  and  the
                    relevant sub-sequence of commands [CAVEAT!].

     Semantics:
                    The expression is first evaluated and  if  a  case
                    exists   which   has  a  constant  with  the  same
                    arithmetic Value then execution is resumed at that
                    label; otherwise, if there is a default label then
                                                    _______
                    execution is continued from there, and if there is
                    not,  execution  is  resumed just after the end of
                    the switchon command.

                    The switch is implemented as a  direct  switch,  a
                    sequential  search  or  a tree search depending on
                    the number and range of the case constants.
                    The case label

                    case E1 to E2:
                    ____       __

                 is equivalent to

                    case E1: case (E1+1): case (E1+2): ...  case E2:
                    ____     ____         ____              ____

                 where E2 must not be less than E1.
                 NOTE: branchon is a synonym for switchon.
                       ________                  ________

BCPL Reference Manual                               Page  35
Commands


     5.14  loop, break, and endcase Commands
           ____  _____  ___ _______ ________

     Syntactic form:

                    loop
                    ____

                    break
                    _____

                    endcase
                    _______

     Examples:
                 1. for i ← 1 to v|0 do
                    ___       __     __
                    { let x ← v|i
                      ___
                      if x = 0 then loop
                      __       ____ ____
                      - - - 
                      - - -
                    L1:
                    ⎇

                 2. until j = 0 do
                    _____       __
                    { if A > CaseK|j then break
                      __             ____ _____
                      CaseK|(j+1) ← CaseK|j
                      CaseL|(j+1) ← CaseL|j
                      j ← j - 1
                    ⎇
                    L2:

                 3. switchon Op into
                    ________    ____
                    { case SWITCHON: Transwitch (x) ; endcase
                      ____                            _______
                      case SEQ:   Trans (x|1) ; endcase
                      ____                      _______
                      default:   Trans(x|2) ; endcase
                      _______                 _______
                    ⎇
                    L3:


     Semantics:
                    The loop command causes a jump to a program  point
                        ____
                    just  inside  the smallest enclosing loop, so that
                    the end condition is tested and the loop  repeated
                    as  required.   In  a for command the loop command
                                          ___             ____
                    also causes the index to be incremented before the
                    test  is  made  (as usual).  In the first example,
                    this is the program point labelled L1.   Execution
                    of  the  break  command causes a jump to the point
                             _____
                    just after the smallest textually  enclosing  loop
                    introduced by one of the following reserved words:
                    until, while, repeat, repeatwhile, repeatuntil and
                    ______ ______ _______ ____________ ___________
                    for.   In  the second example, this is the program
                    ___
                    point labelled L2.  The endcase command  causes  a
                                            _______
                    jump  to the program point just after the smallest
                    textually  enclosing  switchon  command.   In  the
                                          ________
                    third  example, this is the program point labelled
                    L3.

BCPL Reference Manual                               Page  36
Commands


     5.15  finish Command
           ______ _______

     Syntactic form:
                    finish
                    ______

     Semantics:
                    This causes the execution of the program to  cease
                    (HALTF on TENEX).

     5.16  return Commands
           ______ ________

     Syntactic form:
                    return
                    ______

     Semantics:
                    This  causes  the  execution   of   the   smallest
                    enclosing  routine  body  (see  6.10) to cease and
                    return.

     5.17  resultis Commands
           ________ ________

     Syntactic form:
                    resultis E
                    ________

     Semantics:
                    This causes execution of  the  smallest  enclosing
                    valof  expression  (see 4.1.8) to cease and return
                    _____
                    the Value of E.

     5.18  Sections and Blocks
           ________ ___ ______

     Syntactic form:
           { <command or declaration>1<;<command or declaration>>0 ⎇

                    (Notes:  The  semicolon  can  be  omitted  between
                    commands   that  appear  on  separate  lines  (see
                    Appendix A.3).  Square brackets  may  be  used  in
                    place of curly brackets if desired.)

     Semantics:
                    A "section" is a sequence of BCPL commands that is
                    enclosed  in  braces  (braces  are called "section
                    brackets" in  BCPL).   Labels  declared  inside  a
                    section   may   be  referenced  from  outside  the
                    section; e.g., the  program  is  allowed  to  jump
                    (goto)  into  to body of an if command.  A "block"
                     ____                       __
                    is a sequence of BCPL  commands  and  declarations
                    (see  section  6)  that  is  enclosed  in  braces.
                    Labels  declared  inside  a  block  may   not   be
                    referenced  from  outside the block.  A section or
                    block is executed by performing  the  declarations
                    (if  any)  and  commands  in  sequence.   Within a
                    block, the scope of the definee of  a  declaration

BCPL Reference Manual                               Page  37
Commands


                    is   the  region  of  program  consisting  of  the
                    declaration    itself,    and    the    succeeding
                    declarations and commands.

BCPL Reference Manual                               Page  38
Definitions


6.  Definitions
    ___________

     6.1  Scope Rules
          _____ _____

     The SCOPE of a name N is the textual region of program throughout
which  N  refers  to  the  same  "data  item" ( either a variable or a
manifest constant).  Every occurrence (i.e.  use) of a name must be in
the scope of a declaration of the same name.

     There are three kinds of declaration:

       (1)  Each element of the formal parameter list of a function or
            routine:  its  scope  is the function or routine body (see
            6.9 and 6.10).

       (2)  A label set by colon in a block: its scope is the block.

       (3)  Each declaration in a block: its scope is  the  region  of
            program  consisting  of  the  declaration  itself  and the
            succeeding declarations and commands of the block.

     Two data items are said to be  declared  at  the  same  level  of
definition if they were declared in the same formal parameter list, as
labels of the same block, or in the same declarations.

     There are three semantic  restrictions  concerning  scope  rules,
namely:
       (a)  Two data items with the same name may not be  declared  at
            the same level of definition.

       (b)  If a name N is used but not declared within the body of  a
            function  or  routine,  then  it must either be a declared
            manifest constant or a static variable: that is,  it  must
            have  been  declared  as  external,  global,  an  explicit
            function or routine, or a  static.   This  restriction  on
            functions  and  routines  has  been  imposed  in  order to
            achieve a very efficient recursive call.  In terms of  the
            implementation,  this  restriction  states that either the
            Value or  the  Address  of  every  "free  variable"  of  a
            function or routine is known prior to execution.

     Note that the following program is illegal:
                                        _______

               let a,b ← 1,2
               ___
               let f(x) ← a*x + b
               ___

However, it may be corrected as follows:

               static {  a ← 1; b ← 2 ⎇
               ______
               let f(x) ← a*x + b
               ___

       (c)  A label set by colon may not occur within the scope  of  a
            data  item  with  the  same  name  if  that  data item was

BCPL Reference Manual                               Page  39
Definitions


            declared within the scope of the  label  and  was  not  an
            external or global.

     Declarations are permitted intermixed with statements.  The  rule
is  that  a  declaration  may  follow any semicolon, or may follow any
sequence of labels which follows a semicolon.  The  scope  of  such  a
declaration  is to the end of the smallest enclosing section or block.
Note that it is not the case that a declaration  may  appear  anywhere
that  a  label  may.   (For  example,  an  arm of a conditional may be
labelled but it  may  not  be  a  declaration.)  Since  a  declaration
introduces a block, it follows that labels and case labels that appear
after it are not accessible from outside it (CAVEAT!).

     6.2  Space Allocation and Extent of Variables
          _____ __________ ___ ______ __ _________

     The EXTENT of a variable is the time through which it exists  and
has  an  Address.   Throughout  the  extent of a variable, its Address
remains constant and its Value is changed only by assignment.

     In BCPL, variables can be divided into two classes,

       (1)  Static variables:

            Those variables whose extent lasts as long as the  program
            execution  time.   Every  static  variable  must have been
            declared either in a function or routine definition, or in
            an  external,  global,  or static declaration.  For static
            variables that are initialized  to  tables  or  vecs,  the
            space  for  the  table  or  vec has the same extent as the
            static variable.


       (2)  Dynamic variables:

            Those variables whose extent is limited; the extent  of  a
            dynamic  variable  starts when its declaration is executed
            and continues until execution  leaves  the  scope  of  the
            declaration.   Every  dynamic  variable  must  be declared
            either by a simple declaration, a vector declaration or as
            a formal parameter.

     6.3  Externals
          _________

     Syntactic form:
                    external { <name> <;<name>>0⎇
                    ________

     Semantics:
                    The external declaration declares a set  of  names
                    (6  character  length limit in TENEX BCPL for each
                    such name) to be  used  in  common  by  separately
                    compiled  programs.   For  each such name, exactly
                    one program must declare the name as  a  function,
                    routine,  or  static variable.  Within the program

BCPL Reference Manual                               Page  40
Definitions


                    where the name is defined, it must also appear  in
                    an  external  declaration.  Within a program where
                        ________
                    the name is used, it must appear  in  an  external
                                                              ________
                    declaration.   The  programs  that  use  the  name
                    should be loaded with the program that defines the
                    name, otherwise the loader will complain.

     6.4 Globals
         _______

     Syntactic form:
                    global { <name>:<number> <;<name>:<number>>0⎇
                    ______

                    (Note: left arrow (←) may be used in place of : in
                    global, static, and manifest declarations)
                    ______  ______      ________

     Semantics:
                    Globals are very similar to externals, except that
                    numbers are used to identify them.  Global numbers
                    are to be allocated by the user.  In  TENEX  BCPL,
                    he  may  use  numbers  between #400 and #777.  The
                    numbers between 0 and #377 are  reserved  for  the
                    libraries.    Globals   exist  in  TENEX  BCPL  in
                    addition to externals only because the  number  of
                    characters  in the name of an external on TENEX is
                    limited to 6; the number of characters in a global
                    name  is  the same as for any BCPL name (less than
                    24).

     6.5  Statics
          _______

     Syntactic form:
                    static { <name>:<constant> 
                    ______
                             <; <name>:<constant> >0 ⎇

     Semantics:
                    This declares each name to have an  initial  Value
                    equal  to  the  Value  of  the  specified constant
                    expression.  Expressions composed of constants and
                    the operators

                         + - * / $ " ' table vec ,, rem
                                       _____ ___    ___

                    are allowable.  When used  in  this  context,  vec
                                                                   ___
                    denotes a static vector.


BCPL Reference Manual                               Page  41
Definitions


     6.6  Manifests
          _________

     Syntactic form:
                    manifest { <name> : <constant>
                    ________
                                <;<name> : <constant> >0 ⎇

     Semantics:
                    This declares each name to be a manifest  constant
                    with  a  Value equal to the Value of the specified
                    constant expression.  The  meaning  of  a  program
                    would  remain  unchanged  if  all  occurrences  of
                    manifest named constants were  textually  replaced
                    by their corresponding Values.

     6.7  Simple Variables
          ______ _________

     Syntactic form:
                    let N1, N2,..., Nn←E1, E2,..., En
                    ___

     Semantics:
                    Dynamic variables with names N1 ...  Nn are  first
                    declared,   but  not  initialized,  and  then  the
                    following assignment command is executed

                    N1, N2,..., Nn←E1, E2,..., En

     6.8  Vectors
          _______

     Syntactic form:
                    let N1, N2,..., Nn ← vec E1, vec E2,..., vec En
                    ___                  ___     ___         ___

                    where the Ni are names.

     Semantics:
                    Processing is similar to  6.7,  above.   The  Ei's
                    must  be  expressions  which  can  be evaluated at
                    compile time.  Each of these defines  the  maximum
                    allowable  subscript  of the corresponding vector.
                    The minimum subscript is always zero.  The initial
                    Value  of  each  Ni  is  the Address of the zeroth
                    element  of  the  vector;  the  Ni   are   dynamic
                    variables.   The  vector subscripting operation is
                    described in section 4.1.10.

     6.9  Functions
          _________

     Syntactic form:
                    let N(<list of names, separated by commas>)←E
                    ___

                    where N is a name.
     Semantics:
                    This defines a function and a static variable with
                    name  N  whose conceptual type is "function".  The

BCPL Reference Manual                               Page  42
Definitions


                    static variable N has its Value initialized (prior
                    to   execution  of  the  program)  to  the  memory
                    location of the start of the compiled code for the
                    "function  body" (E).  Syntactically, E can be any
                    expression.  N defines an external if it is in the
                    scope  of  an  external  declaration  for  N, or a
                    global  if  it  is  in  the  scope  of  a   global
                    declaration for N.  The names in the name list (if
                    any) are called formal parameters and their  scope
                    is  the  function  body  (E).   Each is a variable
                    which  is  initialized  to  the   Value   of   the
                    corresponding  parameter  in the call (see 4.1.9).
                    The extent of a formal parameter  lasts  from  the
                    moment  of  its initialization in a call until the
                    time when the evaluation of the body is  complete.
                    The  Value  of the function application expression
                    is the Value of E.  All functions and routines may
                    be   defined   and   used  recursively.   Function
                    applications are described in section 4.1.9.

     6.10  Routines
           ________

     Syntactic form:
                    let N(<list of names, separated by commas>) be C
                    ___                                         __

                    where N is a name.

     Semantics:
                    This defines a routine with  name  N.   A  routine
                    declaration  is like a function declaration except
                    that the body  of  a  routine  is  a  command  and
                    therefore  its  application  may not be used as an
                    expression.  A routine should  therefore  only  be
                    called  in  the  context of a command.  A function
                    may be called either as  an  expression  or  as  a
                    command.   Routine  calls are described in section
                    5.3.

     6.11  Simultaneous Definitions
           ____________ ___________

     Syntactic form:
                    let D <and D>0
                    ___    ___

                          NOTE: ...and let...  is allowed
                                   ___ ___

     Semantics:
                    All  the  declarations  are  effectively  executed
                    simultaneously  and all the defined variables have
                    the same scope  which  includes  the  simultaneous
                    definition  itself;  a  set  of mutually recursive
                    functions and routines may thus be declared.

BCPL Reference Manual                               Page  43
Structures


7.  Structures
    __________

   7.1 Introduction
       ____________

     An important problem in programming has to do with accessing  and
changing  subfields  of  structured  data.   Here the term "structured
data" refers to any collection of data -- that is, of  bits  --  which
has  some  structure  meaningful to one or more programs.  As a simple
example, a compiler is concerned with the instruction  format  of  the
object  computer.  Specifically, on the PDP-10, the 36-bit instruction
word is divided into bit fields as follows (from left to right)...

          op   9    operation code
          ac   4    accumulator spec
          d    1    indirect (defer) bit
          x    4    index register specification
          ad   18   address

     Here for each field we give a one  or  two  character  name,  the
width  of  the field in bits, and its function (which is irrelevant to
the present discussion).  Now consider a compiler written  to  compile
code  for  this  machine.   If  jj  is a variable containing the index
register desired, the command

          w ← (w & #777760777777) \ ((jj & #17) lshift 18)
                                                ______

might be used to set the index part of w.  If y is  a  pointer  to  an
instruction, then the command

          rv y ← (rv y & #777760777777) \ ((jj & #17) lshift 18)
          __      __                                  ______

might be used instead.  It would clearly be desirable to  be  able  to
program  this operation in a more transparent manner.  It is this sort
of problem that the structure definition facility  described  in  this
section helps to alleviate.

     Let us continue with the above example.  In the syntax  about  to
be described, the instruction format given above might be described by
the following structure declaration:

               structure
               _________
                 {  instruction
                    {  op     bit 9 //operation code
                              ___
                       ac     bit 4 //accumulator spec
                              ___
                       d      bit 1 //indirect address
                              ___
                       x      bit 4 //index register spec
                              ___
                       ad     bit 18 //address
                              ___
                    ⎇
                 ⎇


     This  declaration  defines  the  name  "instruction"   as   being
associated with a structure, the structure being composed of fields of

BCPL Reference Manual                               Page  44
Structures


bits as shown.  The dot is used to indicate sub-structure, so that

                         instruction.x

refers to the x-part (that is, the index part) of an instruction.   We
can then refer to the index part of the word pointed to by y as

                         y >> instruction.x

The mark ">>", which may be  read  "right  lump",  has  been  selected
because  of  its  resemblance  to a pointer.  It indicates that we are
concerned with a subfield of a word pointed to.  If instead w were the
actual  word  in  question instead of being a pointer to that word, we
might write

                         w << instruction.x

(the "<<" may be read as "left lump").  The statements  given  earlier
might then be written as

                         w << instruction.x ← jj

                         y >> instruction.x ← jj

respectively.   These  forms  are  more  readable.    Similarly,   the
"indirect"  bit of the instruction pointed to by p could be set to one
by executing

                         p >> instruction.d ← 1

The structure facility  in  BCPL  permits  convenient  access  to  and
changing  of  subfields  of  Values.   An  important  advantage of the
facility is that the description of data bases can  be  separated  (in
seperate  "get"  files fetched by the compiler--see Appendix A.3) from
the code that manipulates them.  The idea is to specify the "shape" of
a  data  item  --  its representation as a bit pattern in memory.  The
shape of a data item is, in general, distinct from its use.

   7.2 Syntax
       ______

     Three structure constructs are included in the  language  --  the
<structure  declaration>,  the  <structure  reference>,  and  the size
                                                                  ____
expression.  The first may be used wherever a declaration may  be  and
serves  to  declare  that  a  particular  name references a particular
structure, or shape.  The  second  may  be  used  wherever  a  primary
expression  may  be  used and serves to access a structured item.  The
last may be used to compute (as a constant  expression)  the  size  in
bits of a structure.

     BNF syntax follows, using the usual notation.  Names of syntactic
classes  are  enclosed  in angle brackets, the vertical bar "|" is the
meta-linguistic OR, and "::=" means "is defined  to  be".   All  other
characters stand for themselves.

BCPL Reference Manual                               Page  45
Structures


     Syntax for structure declarations:

<structure declaration>  ::=
                     structure { <sd-list> ⎇
                     _________
       <sd-list> ::=
              <sd-item>  |  <sd-item> ; <sd-list>
       <sd-item> ::=
              <sd-term> | <sd-term> overlay <sd-item>
                                    _______
       <sd-term> ::=
              <name> <replicator> <declarator> <size>
             | <declarator> <size>
             | fill <declarator>
               ____
             | <name> <replicator> ; { <sd-list> ⎇
             | { <sd-list>⎇
       <replicator> ::=
              ↑ <constant expression>
              | ↑ <constant expression> ↑ <constant expression>
             | <empty>
       <declarator> ::=
       bit | bitn | bitb | byte | byten | char | word
       ___   ____   ____   ____   _____   ____   ____
       <size> ::=
              <constant expression> | <empty>

     Syntax for structure references:
       <structure reference> ::=
              <expression> >> <sri>
             | <expression> << <sri>
       <sri> ::=
              <src> | <src> . <sri>
       <src> ::=
              <name> | <name> ↑ <expression>

In addition, add to the definition of <constant expression> 
the possibility

             | size <sri>
               ____

The syntactic categories left undefined in this syntax are

       <expression>    any expression
       <constant expression> any expression whose Value 
                       can be deduced at compile time
       <name>          any name


   7.3 Semantics
       _________

     A <structure declaration> is a list of <sd-item>s,  separated  by
semicolons.    (The   semicolons   missing  from  the  examples  shown
throughout this  document  would  be  inserted  automatically  by  the
compiler.)  Each  <sd-item>  is  one  or more <sd-term>s, separated by
overlays.   Ignoring  this  possibility  for  the  moment,  assume  an
_______
<sd-item>  to be an <sd-term>.  The interest comes in an <sd-term>, of

BCPL Reference Manual                               Page  46
Structures


which there are five flavors.  As an example of the first, consider

              x bit 5
                ___

this specifies a field named "x" which is 5 bits wide.  The <sd-term>

              y↑3 bit 7
                  ___

specifies three replications of field "y", each  replication  being  7
bits   wide.   The  "up  arrow"  indicates  a  structure  subscripting
operator,  used  in  both  declarations  and  references.   The  three
instances  of  y  would be referred to as y↑1, y↑2 and y↑3.  Note that
the first has "subscript" 1, as opposed to the usual BCPL subscription
convention  in  which  the  first  item  has  "subscript"  zero.   The
difference   between   structure   subscripting   and   regular   BCPL
subscripting   is  emphasized  by  using  different  characters.   Now
consider the declaration

              z↑0↑2 bit 7
                    ___

This uses as much space as the previous example, but the fields are to
be  referred  to  as  z↑0,  z↑1  and  z↑2.   We  see  then that if the
replicator is absent, it is taken as one.  If one value is  given  (as
for  y  above),  it  is  taken as the upper limit with the lower limit
taken as one.  If two fields are given, they are taken  as  the  lower
and upper limits, respectively.

     Consider now the classes <declarator> and <size>.   The  keywords
bit,  byte  and word are self-explanatory, although the number of bits
___   ____      ____
in a byte and  of  bytes  in  a  word  are  of  course  implementation
dependent.   On  TENEX, both char and byte represent 9-bit fields.  In
                             ____     ____
most implementations char would be the same as byte but  they  may  be
                     ____                      ____
different.   (Even  if  they are identical, the programmer may find it
convenient to think of some items as  char  and  some  as  byte.)  The
                                      ____                 ____
declarators  bitn and byten refer to numeric fields.  When referenced,
             ____     _____
they are taken as signed quantities and treated as appropriate in  the
implementation.   For example, in a computer using one's complement or
two's complement arithmetic the leftmost bit of  the  field  would  be
copied  into  all  bits  of  the  word  to the left of the field.  The
declarator bitb signifies a Boolean field and is  permitted  only  for
           ____
fields  of  width  one.   Accessing such a field yields either true or
                                                               ____
false.
_____

     An <sd-term> such as <declarator> <size> may be used to leave  an
unnamed  field  of  the  given  width.   Such fields may straddle word
boundaries, even though named fields may not.

     The <sd-term>s fill byte and  fill  word  represent  fields  wide
                    ____ ____      ____  ____
enough to go to the next byte boundary or word boundary, respectively.
No name is associated with these, as they are used only to insure that
the  next  field  starts on an appropriate boundary.  Since a subfield
may not extend over a word boundary,  this  is  frequently  necessary.
Use  of  fill  frequently  permits  a  given declaration to be used on
         ____

BCPL Reference Manual                               Page  47
Structures


different computers with different word lengths.

     Note carefully the restriction alluded to above: a named field is
not permitted to extend over a word boundary.  Thus the declaration

              structure { a { b bit 27 ; c bit 27 ⎇ ⎇
              _________         ___        ___

is improper on a machine with a 36-bit word, since a.c extends over  a
word boundary.  Also illegal is

              structure { a↑2 bit 27 ⎇
              _________       ___

since a↑2 is bad.  There is no restriction about extending  over  byte
boundaries, so the declaration

              structure { a { b bit 5 ; c byte ⎇ ⎇
              _________         ___       ____

is correct.  Another way to look at this is that the <sd-term> byte is
                                                               ____
synonymous with the <sd-term> bit 9 (on TENEX), and
                              ___

              structure { a { b bit 5 ; c bit 9 ⎇ ⎇
              _________         ___       ___

is clearly acceptable.  Also acceptable is

              structure { a char 3; char 2; b char 3 ⎇
              _________     ____    ____      ____

on a computer with 4 char's per word, since the field  that  straddles
                     ____
the word boundary is unnamed.

     The <size> specifies the width of the  field,  in  units  of  the
<declarator>.  If missing it is taken as one.  Thus byte 3 refers to a
                                                    ____
field three bytes wide.  The <size> may be any expression that can  be
evaluated at compile time.

     All that remains to be explained is  the  keyword  overlay.   Two
                                                        _______
<sd-term>s  separated  by  overlay  are  to  occupy  the same storage.
                           _______
Consider, for example, the declaration

structure { a { b byte 2; c byte 2 overlay cn byten 2 ⎇ ⎇
_________         ____      ____   _______    _____


     The reference x<<a.b refers to the left half  of  x,  and  x<<a.c
refers to x's right half.  (This example assumes four bytes per word.)
However, x<<a.cn interprets x's right half as a numeric  quantity,  so
that  it  would  be  accessed  with sign extension.  That is, c and cn
refer to the same part of the structure.  Consider another example, in
which we assume four 9-bit bytes per word:

structure { a { b byte 2; c↑6 bit 3 overlay d↑3 bit 6 ⎇ ⎇
_________         ____        ___   _______     ___

Here the right half of the word is to  be  regarded  as  either  three
6-bit fields or six 3-bit fields.

BCPL Reference Manual                               Page  48
Structures


   7.4 Examples
       ________

     Following are some examples  of  <structure  declaration>s,  with
comments on their effect.  The examples assume a 36-bit word with four
9-bit bytes per word, as on TENEX.

     A string in BCPL on TENEX is stored  four  characters  per  word,
with  the  length  (in characters) stored in the first (leftmost) byte
position.  (The BCPL convention for structures is that byte  positions
are  counted  from  left  to  right.)  Then  a  declaration for such a
structure is

              structure { string { n byte; c↑511 char ⎇⎇
              _________              ____        ____

With this declaration, the length in bytes of string x may be referred
to  as x>>string.n, and the 4-th character of x as x>>string.c↑4.  The
number 511 in the declaration comes from the  fact  that  the  maximum
string  length  must  be  storable in 9 bits.  The maximum length of a
string in words is given by the expression

              (size string)/36
               ____

(the parentheses are not needed.) This expression has value 128 (given
the  above  declaration  of  string  on TENEX) and is capable of being
evaluated at compile time, so that

              let v = vec (size string) / 36
              ___     ___  ____

is permissable.  Note that the structure declaration of  string  would
be  less  useful  had n been declared to be a numeric field with byten
                                                                 _____
rather than byte.  In that case the left-most bit would be interpreted
            ____
as  a sign bit, so the possible values storable in a 9-bit field would
be  from  -256  to  255.    Since   negative   string   lengths   seem
uninteresting,  declaring  the field to be a byte field gives the more
useful range of 0 to 511.

     Sometimes it is convenient to store  strings  one  character  per
word.   A  useful format is to put the length in the zero-th word of a
vector and the characters in successive words.  Routines for unpacking
and packing strings are then like this:

let unpackstring(s, v) be  // unpack string s into vector v
___                    __
{ v|0 ← s >> string.n      // the length of the string
  for k ← 1 to v|0 do v|k ← s >> string.c↑k ⎇
  ___       __     __

and packstring(v, s) be  // pack vector v into string s
___                  __
 {   s >> string.n ← v|0
   for k ← 1 to v|0 do s>>string.c↑k ← v|k ⎇
   ___       __     __

Note the rather pleasant symmetry between these two routines.

     Here is a routine that reverses the bits of a word:

BCPL Reference Manual                               Page  49
Structures


       let reverse(x) ← valof
       ___              _____
       {  structure { b↑0↑35 bit 1 ⎇ // 36 1-bit items
          _________          ___
          let t ← 0
          ___
          for n ← 0 to 35 do t << b↑n ← x << b↑(35-n)
          ___       __    __
          resultis t ⎇
          ________

The value of the function is the bit-reverse of its input.

BCPL Reference Manual                               Page  50
Structures


                         REFERENCES

     [1]  Strachey, C.  (Editor)  "CPL  Working  Papers"  a  technical
          report,   London  Institute  of  Computer  Science  and  the
          University Mathematical Laboratory, Cambridge (1966).

     [2]  Richards, M.  "The BCPL Reference Manual", Project MAC  Memo
          M-352-1, M.I.T.  Cambridge, Mass.  (Feb.  1968).

     [3]  Richards, M.  "BCPL: A tool for Compiler Writing and  System
          Programming", 1969 Spring Joint Computer Conference.
     [4]  The TENEX JSYS Manual

BCPL Reference Manual                               Page  51
Appendices


                         APPENDICES

A.  BCPL Characteristics

     A.1 Reserved Words and Symbols
         ________ _____ ___ _______

     The  reserved  words  and  symbols  of  BCPL  are  implementation
dependent:  they  depend  on  the character set that is available.  To
simplify the transfer of BCPL from one machine to another,  a  set  of
"canonical  symbols"  has  been developed.  Each implementation of the
BCPL compiler has a preprocessor which translates the  reserved  words
and  symbols  for that implementation into the canonical symbols.  The
"canonical representation" of a BCPL program consists of a sequence of
canonical symbols.

     The names of the canonical symbols are given below together  with
corresponding examples of how they are represented in TENEX BCPL.  The
list of words and symbols under 'TENEX  Form'  includes  the  list  of
TENEX BCPL reserved words and symbols.

     Canonical           TENEX                    Described
     _________           _____                    _________
      Symbol             Form                     in Section
      ______             ____                     __ _______

     number              103 #777 3.56            4.1.1
     name                abc  i  H2               4.1.4
     stringconst         'xyz*n'  "p"             4.1.3
     charconst           $a  $3                   4.1.2
     true                true                     4.1.5
     false               false                    4.1.5
     nil                 nil                      4.1.6
     valof               valof                    4.1.8
     lv                  lv                       3.1, 4.1.11
     rv                  rv                       3.1, 4.1.12
     lh                  lh                       4.1.13
     rh                  rh                       4.1.13
     lhz                 lhz                      4.1.13
     rhz                 rhz                      4.1.13
     mult                *                        4.2
     div                 /                        4.2
     rem                 rem                      4.2
     plus                +                        4.2
     minus               -                        4.2
     fplus               %+                       4.2
     fminus              %-                       4.2
     fmult               %*                       4.2
     fdiv                %/                       4.2
     eq                  eq or  =                 4.3
     get                 get                      A.3
     size                size                     7.2
     offset              offset                   7.2
     ne                  ne                       4.3
     ls                  ls or < or lt            4.3
     gt                  gt or > or gr            4.3

BCPL Reference Manual                               Page  52
Appendices


     ge                  ge                       4.3
     le                  le                       4.3
     not                 not or }                 4.5
     lshift              lshift                   4.4
     rshift              rshift                   4.4
     lscale              lscale                   4.4
     rscale              rscale                   4.4
     logand              logand or &              4.5
     logor               logor or \               4.5
     eqv                 eqv                      4.5
     neqv                neqv or xor              4.5
     cond                => or ->                 4.7
     comma               ,                        4.7
     table               table                    4.8.1
     list                list                     4.8.2
     and                 and                      6.10
     ass                 ← or :=                  5.1
     goto                goto                     5.5
     resultis            resultis                 5.17
     colon               :                        5.4
     test                test                     5.10
     ifso                ifso                     5.10
     ifnot               ifnot                    5.10
     for                 for                      5.12
     if                  if                       5.6
     unless              unless                   5.7
     while               while                    5.8
     until               until                    5.9
     repeat              repeat                   5.11
     repeatwhile         repeatwhile              5.11
     repeatuntil         repeatuntil              5.11
     loop                loop                     5.14
     break               break                    5.14
     return              return                   5.16
     finish              finish                   5.15
     switchon            switchon                 5.13
     branchon            branchon                 5.13
     selecton            selecton                 4.9
     case                case                     5.13,4.9
     default             default                  5.13,4.9
     endcase             endcase                  5.14
     let                 let                      6.2
     manifest            manifest                 6.5
     static              static                   6.4
     external            external                 6.3
     global              global                   6.11
     be                  be                       7.2
     sectbra             { or [                   5.18
     sectket             ⎇ or ]                   5.18
     rbra                (                        4.1.7
     rket                )                        4.1.7
     structure           structure                7
     char                char                     7

BCPL Reference Manual                               Page  53
Appendices


     fill                fill                     7
     word                word                     7
     overlay             overlay                  7
     bit                 bit                      7
     bitb                bitb                     7
     bitn                bitn                     7
     byte                byte                     7
     byten               byten                    7
     semicolon           ;                        5
     into                into                     5.13
     to                  to                       5.12
     by                  by or step               5.12
     do                  do or then               5.12
     or                  or                       5.10
     vec                 vec                      6.7  
     vecap               | or !                   4.1.10
     uplump              ↑                        7.2
     leftlump            <<                       7.2
     rightlump           >>                       7.2
     dot                 .                        7.2

     A.2 The TENEX BCPL Character Set
         ___ _____ ____ _________ ___

Code(Octal)  Char      Usage in BCPL source program
000          ↑@        Null ... Ignored as if it weren't there
001,006      ↑A,↑F     Illegal
007          ↑G        Bell ... Illegal
010          ↑H        Backspace ... Illegal
011          ↑I        Tab ... Ignorable, like space
012          ↑J        Line feed ... Taken as "End Of Line"
013          ↑K        Vertical tab ... Illegal
014          ↑L        Form Feed ... Ignorable
015          ↑M        Carriage Return ... Ignorable
016,031      ↑N,↑Y     Illegal
032          ↑Z        [Terminate input stream to the compiler] EOF
033          Altmode   Illegal
034,036      ↑\,↑],↑↑  Illegal
037          ↑←        TENEX EOL, BCPL "*n", taken as "End Of Line"

040          Space     Ignorable
041          !         VECAP
042          "         Quote Character for BCPL strings
043          #         Octal number prefix
044          $         Character constant "quote"
045          %         Floating-point operation prefix %+ %- %/ %*
046          &         Logical AND operator
047          '         Quote character for ASCIZ strings
050          (         Expression parenthesis
051          )         Expression parenthesis
052          *         Integer multiply operator
053          +         Integer add operator
054          ,         COMMA
055          -         Integer subtract operator

BCPL Reference Manual                               Page  54
Appendices


056          .         Structure operator and decimal point for 
                       floating point numbers
057          /         Integer divide operator

060,071      0,9       Digits

072          :         COLON (for labels)
073          ;         SEMICOLON
074          <         LS operator
075          =         EQ operator
076          >         GR operator
077          ?         Illegal
100          @         If /U, character or word upper case escape char
                       otherwise, ignored as if it weren't there (see
 B.2)
101,132      A,Z       Uppercase letters (mapped to lower case, if /U)
133          [         Optional SECTBRA
134          \         Logical OR operator
135          ]         Optional SECTKET
136          ↑         UPLUMP (structure operator)
137          ←         assignment operator

140          `         (grave) Illegal
141,172      a,z       Lowercase letters

173          {         SECTBRA
174          |         VECAP
175          ⎇         SECTKET
176          }         Logical NOT operator
177          Rubout    Illegal (BCPL "*r")


                         Escape    conventions    for     non-printing
                    characters and control characters in character and
                    string constants are defined for TENEX BCPL.

                    Example:       $*s   represents space
                                   $**   represents *
                                   $↑a   represents control a
                                   $*↑   represents ↑

                    A  complete  description  of   these   conventions
                    follows:
↑x where x in { [,\,],↑,a, ... ,z ⎇ => that control character

*n => code 37, TENEX EOL (new line)
*r => code 177, Rubout
*s => code 40, Space
*t => code 11, Tab
*b => code 10, Backspace
*p => code 14, "Page", form feed
*f => code 14, form feed
*v => code 13, vertical tab

BCPL Reference Manual                               Page  55
Appendices


*<Three Octal digits> => octal escape 
*c => code 15, carriage return
*l => code 12, line feed
*↑ => code 136, ↑
*" => code 42, "
*' => code 47, '
** => code 52, *
*$ => altmode
*a => code 100, @
*e => code 777, end of stream
*d => code 0, @ (NULL, dummy character)

     A.3 The BCPL Preprocessor
         ___ ____ ____________

     The Preprocessor is the name of the part  of  the  BCPL  compiler
which  transforms  the  raw  source  text  of a program into canonical
symbols.  The conventions in the TENEX version are as follows:

     (a)  A name is any sequence of upper or lower  case  letters  and
          digits,  starting  with  a  letter,  which is not a reserved
          word.  The character immediately following a name may not be
          a  letter  or  digit.   A  name  may  be  no  longer than 23
          characters.  All reserved words are strings of two  or  more
          lowercase letters.

     (b)  User's comments may be  included  in  a  program  between  a
          double slash '//' and the end of the line.  Example:
             let Factorial(n) ← valof
             ___                _____
              { // This function returns the factorial of 
                //   its argument.
                
                if n = 1 do resultis 1
                __       __ ________
                resultis n * Factorial(n-1)
                ________
              ⎇

     (c)  For documentation purposes, section brackets may  be  tagged
          with  a  name  or integer.  CAVEAT: Section bracket tags are
          detected as a name or integer which is immediately  adjacent
          to the bracket.  Thus, section brackets which are not tagged
          must be separated from a following letter or digit by space,
          tab, or carriage return.

     (d)  The  canonical  symbol  semicolon   is   inserted   by   the
          preprocessor  between  pairs  of  canonical  symbols if they
          appear on different lines and if the first is from  the  set
          of  canonical symbols which may end a command or definition,
          namely:

               break return finish repeat rket endcase loop nil 
               sectket name stringconst number true false charconst

          and the second is from the set of  canonical  symbols  which
          may start a command, namely:

BCPL Reference Manual                               Page  56
Appendices


               test for if unless until while goto resultis
               case default break return finish sectbra
               switchon endcase loop selecton branchon
               charconst not lhz rhz number strinconst 
               rbra valof rv name rh lh q1 q2 q3 q4

     (e)  The canonical symbol "do" is inserted  by  the  preprocessor
          between  pairs  of  canonical  symbols if they appear on the
          same line and if the first is  from  the  set  of  canonical
          symbols which may end an expression, namely:

               rket sectket name number
               stringconst true false charconst nil

          and the second is from the set of  canonical  symbols  which
          must start a command, namely:

               test for if unless until while goto
               resultis endcase loop 
               case default break return finish switchon branchon

     (f)  A directive of the form:

               get <specifier>

          may be used anywhere in  a  BCPL  program;  it  directs  the
          compiler  to  replace  the directive with the file (of text)
          referred to by the specifier.  The form of the specifier  is
          a string constant (the file name: see the example program in
          Appendix B).

     (g)  Pseudo commands *********:::::::::*********
      A.4  Glitches ***********::::::::::**********
           ________

B.  Usage of TENEX BCPL

     B.1 Typical Source File Organization

     By convention, the file name extension for BCPL source  files  is
.BCP .   A  BCPL  source  file  normally  starts  with a comment which
describes the contents of the file.  Following this, there are usually
declarations  of  externals, globals, statics, and manifests which are
to be in effect during  the  compilation  of  the  source  file.   For
convenience,  collections  of  standard declarations are often kept in
separate text files (example: GLOBAL declarations for the I/O  library
are contained in <BCPL>HEAD.BCP); the "get" command tells the compiler
to insert the text from a specified file into the source,  and  behave
as  if  this  text  were a part of the source.  Thus, the "declaration
portion" of the BCPL source file often contains "get"  commands.   See
the example program, below.

     B.2 Using the Compiler

BCPL Reference Manual                               Page  57
Appendices


     The BCPL compiler is the subsystem named "BCPL.SAV".  Its primary
job  is to translate a BCPL source file into a TENEX .REL file.  Other
jobs that it does include the generation of a  MACRO  listing  of  the
program,  and the generation of a specially-formatted symbol table for
the program.  Typing "?"  will  cause  the  compiler  to  explain  its
command  line format.  The CCL subsystem will select the BCPL compiler
for compilation of .BCP files.

     B.3 Constructing a BCPL Main Program

     Compile a BCPL source program which contains the definition of  a
routine  named  "Start",  with  "Start"  declared  as GLOBAL #1 (as in
<BCPL>HEAD.BCP).  Then load the resulting .REL file (and any  others).
The  BCPL library (<SUBSYS>BCPLIB.REL) will be searched automatically.
Starting the resulting core image will cause the routine named "Start"
to  be  called.   Returning  from  "Start"  will  cause the program to
terminate (HALTF).

     B.4 Routine and Function Linkage Conventions
            1.  Calling Sequence

            call:
              ...         ;CODE TO STUFF ARGS
                          ;AND NUMBER OF ARGS
                          ;INTO THE NEW STACK FRAME
              ADDI 16,n   ;MOVE THE STACK POINTER
                          ;TO THE NEW STACK FRAME
              JSP 1,subr  ;CALL THE ROUTINE OR FUNCTION
              SUBI 16,n   ;MOVE THE STACK POINTER
                          ;BACK TO THE OLD STACK
                          ;FRAME


                       at routine or function entry:

              MOVEM 1,0 (16) ;SAVE THE RETURN POINTER
                          ;IN THE CURRENT STACK FRAME


                       Routine or function return:

              JRST 2,@0(16) ;RESTORE FLAGS AND RETURN

            2.  On entry to a  routine  or  function,  the  number  of
                arguments is expected to be in 1(16)

            3.  The first argument is expected to be in 2(16) 
                The kth argument is expected to be in k+1(16)

            4.  Only register 16 is expected to be preserved across  a
                routine or function invocation.

BCPL Reference Manual                               Page  58
Appendices


            5.  n is the size of the current stack frame.
                This is equal to
          2+
          number of args declared in the currently active  routine  or
          function +
          number of registers for local variables on the stack in  the
          currently active routine or function when the call is made.

            6.  subr is the address of a  register  which  contains  a
                JRST  instruction  to  the  first  instruction  of the
                routine or function being called (In BCPL,  the  Value
                of  a  label,  routine,  or  function  is  such a JRST
                instruction).

            7.  The Value of a function call is returned in AC1.

     B.5 Utility Programs

         a.  <BCPL>FMT.SAV

                 This is a program which formats a BCPL  source  file.
            WARNING:  the source file should have no syntactic errors.
            The program is experimental; there are pathological  cases
            which  cause  it  to  mess up.  Use it at your peril.  (We
            find it quite useful).

         b.  <BCPL>OCODE.SAV

                 This is a program which  prints  out  the  compiler's
            intermediate  output code for the idealized object machine
            in a human-readable form.  The program requires a .O  file
            as  its  input;  the  compiler will produce this if the /O
            switch is specified for the compilation.

         c.  <BCPL>PSYMB.SAV

                 This program prints out the symbol table  (i.e.   the
            .S  file)  in a human-readable form.  Its output is to the
            file named <pgm name>.SYMTAB.

         d.  <BCPL>PSAVE.SAV

                 This program prints out useful information  about  an
            SSAVE'd file in which there are BCPL .REL files.

         e.  <BCPL>CONC.SAV

                 This program generates a concordance (CREF)  for  one
            or more BCPL source files.

     B.6.  A Complete, Realistic, Working Example Program

BCPL Reference Manual                               Page  59
Appendices


     A programming example which demonstrates a simple application  of
recursion  is  known  as the "8 Queens Problem".  The problem requires
the placement of eight queens  on  a  standard  8x8  chessboard  in  a
configuration such that no queen threatens any other queen.

     The recursive solution to this problem is a function which:
     1.  Assumes that on entry, there is a queen in each column to the
         left, but there are no conflicts.

     2.  Tries to place a queen in each row  of  the  current  column,
         failing  when it conflicts with any of the queens in previous
         columns.

     3.  For each success above, calls itself recursively  to  iterate
         over  the  next  column to the right.  This will discover all
         non-conflicting configurations to the right (printing them as
         solutions) before returning.


     The argument of the function is the  current  column.   The  data
structures  needed  for  bookkeeping  are vectors indicating that some
queen  is  already  placed  in  a   particular   row,   a   particular
upward-diagonal,  or a particular downward-diagonal, so the attempt to
place another queen in the same row/updiagonal/downdiagonal results in
a  conflict.   In  addition, a solution vector is needed for type-out:
this specifies which row the queen is in for each column.

     The following  example  illustrates  the  use  of  comments,  the
labeling  of  section  brackets,  the  use  of  the get declaration to
                                                    ___
include other files in the  compilation,  the  static  declaration  to
                                               ______
allocate  storage, routine definitions, and the use of several library
functions (WriteN, WriteS) for typeout.  The block structure, the long
identifiers,  (up  to 23 upper/lower case characters) and the mnemonic
operators all contribute to program readability.
// Solution of 8 Queens Problem

get "<BCPL>HEAD.BCP"
get "<BCPL>UTILHEAD.BCP"	// Link to I/O subroutine Library

static { Solutions:	nil	// Total number of legal solutions

	Row:		vec 7	// Array to remember the col
				// the Queen is in for each row 0-7

	Horiz:		vec 7	// True if a queen is in
				// the Horizontal row 0-7

	Updiag:		vec 14	// True if a Queen is in
				// the Upward Diagonal 0-14

	Downdiag:	vec 14	// True if a Queen is in
				// the Downward Diagonal 0-14

	⎇

let Start() be
{st
	for I←0 to 7			// Each Horiz row is empty
	do Horiz|I←false
	for I←0 to 14	// And each diagonal is empty 
		do { Updiag|I←false; Downdiag|I←false ⎇
	OUTPUT←CreateOutput(0)	// Open Teletype Output
	Solutions←0		// No solutions yet
	Queens(0)		// Types out all solutions
	WriteS("*n Number of Solutions= ")
	WriteN(Solutions)	// Summary
⎇st

and Queens(Col) be		//  There are no conflicts in previous
				// columns
{qn	let Updiag2,Downdiag2←Updiag+7-Col,Downdiag+Col
	for N←0 to 7		// Try to put a Queen in each row
	do			// of this column
		 unless (Horiz|N \ Updiag2|N \ Downdiag2|N)
		do	// No conflict with queens to left
			{ Row|Col←N  // Remember where for typeout
			test Col=7	// Check for all done
			ifso
				{ WriteS("*n") // Legal Solution
				for Col←0 to 7
				do { WriteN(Row|Col); WriteS("*s") ⎇
				Solutions←Solutions+1
				⎇
			ifnot	{ Horiz|N←true // Place a Queen there
				Updiag2|N←true
				Downdiag2|N←true
				Queens(Col+1) // Find all legal configs
					      // in cols to the right
				Horiz|N←false // Now remove Queen
				Updiag2|N←false
				Downdiag2|N←false  
				⎇
			⎇
⎇qn







APPENDIX C.  Functions, Routines, and Special Static Variables in  the
            TENEX BCPL Library

C.1 I/O
C.1.1 I/O Streams

     There are two kinds  of  "BCPL  I/O  streams":  JFN  streams  and
function  streams.   JFN  streams  are  simply  TENEX JFN's.  Function
streams are functions which are specified by the user to be  either  a
source of bytes (for input) or a sink (for output).  We are working on
adding "string streams".

FindInput(Desc,bytesize)
CreateOutput(Desc,bytesize)
      bytesize: (optional argument) assumed to  be  7  (bits)  if  not
               specified.
      Desc:
               -f: use function or routine  (f)  for  I/O.   For  each
                    character  operation, f will be called.  The first
                    arg to f will be the byte size.  The char will  be
                    the second arg (output only).
               0: primary input/output JFN
               1: ask user for string at run time
               2: expect string at run time from primary  input  file,
                    but don't prompt the user.
               s: s is a string ; do GTJFN

      The Values of FindInput and CreateOutput are zero  if  an  error
      occurs, JFN's for the opened files for cases 0, 1, 2, and s, and
      a 36 bit number for case -f as follows:
         q4 = -1 if read, -2 if write
         q3 = bytesize
         right half = rhz(-f)

EndRead(stream,lefthalf)
EndWrite(stream,lefthalf)
      These "close" the  specified  "stream".   In  both  EndRead  and
      EndWrite,  the  second  argument is optional.  If present, it is
      used as the left  half  of  AC1  in  the  CLOSF  call  (for  JFN
      streams).  If absent, 0 is used.

CLOSF(jfn) does just that.

INPUT
      The  default  input  stream  (used   by   PBIN,   for   example)
      (initialized to the primary input stream for this process)

OUTPUT
      The  default  output  stream  (used  by  PBOUT,   for   example)
      (initialized to the primary output stream for this process)

EofFlg
      A static variable which is set by BIN, PBIN,  Readch,  and  SIN.

BCPL Reference Manual                               Page   2
I/O Streams


      Set to true if an EOF is encountered while reading bytes, set to
             ____
      false otherwise.
      _____

rfptr(jfn)
      returns the byte pointer ala jsys RFPTR  or  a  negative  number
      (the negative error number from the JSYS)

sfptr(jfn,byte ptr)
      sets the byte pointer, ala jsys SFPTR.  The first byte in a file
      has byte pointer=0.
      Value: a negative number (the negative of the JSYS error number)
      if the JSYS fails, zero otherwise.

IsCharInput(input stream)
      returns true if there is another input  character  available  on
      the specified input stream.  (uses SIBE for JFN streams)

EchoMode(boolean)
      turns on or off keyboard echoing, ala the argument (true => on).
                                                          ____

BCPL Reference Manual                               Page   3
Character, Word, and String I/O


C.1.2 Character, Word, and String I/O

BIN(stream)
      Read a byte from the specified input stream.

      Value: the byte read.
      Note that if BIN (or PBIN or Readch or SIN) reads  past  End  Of
      File,  the  character  code  returned is #777, and EofFlg is set
      true, otherwise EofFlg is set false.
      ____

PBIN()
      Read a byte from the primary input stream.  
      Value: the byte read.  Note: PBIN() is equivalent to BIN(INPUT)

BOUT(stream,Byte)
      Write a byte on a specified output stream.

PBOUT(Byte)
      Write a byte on the primary output stream.
      PBOUT(Byte) is equivalent to BOUT(OUTPUT,Byte)

Readch( stream, lv Ch) is equivalent to
      Ch ← BIN(stream)

Writech(stream, Ch) (same as BOUT),

      For Readch and Writech, if there is only  one  argument,  it  is
      assumed  to be a character to either read from INPUT or write on
      OUTPUT.

SIN(stream,TENEX string ptr, bytecount, termbyte)
      bytecount:
        0 => 0 byte terminates
        >0 => bytecount
      termbyte: optional argument ; present => use it for  terminating
            byte, if it occurs before the byte count is exhausted.

      Value: if  bytecount  >  0  ,  Value  is  the  number  of  bytes
      transferred.   Otherwise,  Value  is  the  revised  TENEX string
      pointer.

SOUT(stream,TENEX string ptr, bytecount, termbyte)
      same as SIN, but for output

WriteS(String) or WriteS(stream,String).
      Write a BCPL string.  Former case  uses  primary  output  stream
      (OUTPUT).

BCPL Reference Manual                               Page   4
Character, Word, and String I/O


ReadWord(instream,strng,chlv, skipbool)
      reads a word from the specified stream (instream)  as  delimited
      by  "terminators"  (ala  IsTerminator) into the specified buffer
      (strng).   You  can,  of  course,  overlay  the  definition   of
      IsTerminator  with your own function.  The control characters a,
      q, and r may be used.
      If only one  arg,  INPUT  is  used  as  the  instream,  and  the
      specified arg is used as "strng".  
      If lh strng < 0, the word goes into the buffer pointed to by  rh
      strng in unpacked BCPL string format:
         [[(rh strng)|0=# chars ; (rh strng)|i=iTH char]]
      Otherwise, the word goes into strng in the  packed  BCPL  string
      format.   The  (optional)  third  argument specifies the lv of a
      variable into which to store the character which terminated  the
      word.   If  four  arguments  are given, and the fourth is false,
                                                                _____
      then  ReadWord  returns  whenever   it   reads   a   terminator.
      Otherwise,  Readword  skips  over word-initial terminators.  The
      Value of a call on ReadWord is (rh strng).

IsTerminator(ch)
      returns a Boolean: true if the char is *s *t *c *l or *n   
      false otherwise.

BCPL Reference Manual                               Page   5
Integer and Floating Point I/O


C.1.3 Integer and Floating Point I/O
WriteN(number)
      writes the (integer) "number" (in decimal) on the primary output
      stream.
  WriteN(stream,number) does it to the specified stream.

WriteOct(...)
      similar to WriteN, but radix 8

WriteR(stream,n,AC3)
      Write a single precision floating point number 
      1 arg: n: OUTPUT assumed as stream and 0 assumed as AC3 to FLOUT
      2 args: 0 assumed as AC3 to FLOUT
      Value: error code (for ERSTR) if an error is detected; otherwise
      Value is -1.
      A more elaborate  formatted  output  facility  is  described  in
      C.1.5.

ReadN(instream)
      calls ReadWord, (with skipbool = true) then  TxtToInt.   if  the
                                       ____
      argument is missing, INPUT is used.

BCPL Reference Manual                               Page   6
ARPANET Interface


C.1.4 Network Interface
          CreateNetDialogue
          FindNetInput
          CreateNetOutput
          LISTENING
          NETLOCALSOCKET
          NETINOPENF2
          NETOUTOPENF2
          NETWAITTIME
          NETPOLLTIME
          NETWAITFLAG
          LocalSocket
          NetStatus
          EndNetDialogue
          InitNetLibrary

               This section describes a  package  of  subroutines  for
          doing  ARPA Network I/O from BCPL programs, or from programs
          which  can  interface  to  the   BCPL   subroutine   calling
          conventions.   The  (BCPL)  source  file  for the subroutine
          definitions is <BCPL>NL.BCP.  The BCPL head  file  with  the
          GLOBAL declarations is <BCPL>NLHEAD.BCP.  The REL file to be
          loaded with your calling program is  <BCPL>NETLIB.REL.   The
          subroutines  work  and  have  been used to implement several
          programs which use facilities at Lincoln TX-2  and  transfer
          files  both  ways  between  BBN-TENEX  and  TX-2.  Note that
          reference is made in the documentation  to  "error  numbers"
          which  are  returned from the subroutines when they fail for
          some reason.  These aren't described here.

               SUBROUTINES:

               I.  CreateNetDialogue

         CreateNetDialogue(foreign  host,  outstream-lv,  instream-lv,
                 localsocket, foreign socket)

         foreign host: either a BCPL string (the  host  name)  in  the
                 right  half  and  -1  in  the  left half, or the host
                 number.  If left half is negative, then right half is
                 taken as a pointer to a BCPL string.

         outstreamlv and instreamlv: addresses  of  storage  cells  in
                 which  the  two  new  stream  identifiers  are  to be
                 stored.

         localsocket: a local socket  number  (must  be  even).   This
                 argument  is optional.  If it is missing or negative,
                 one is made up.

         foreign socket: 1 (for logger) assumed if  this  argument  is
                 missing.

BCPL Reference Manual                               Page   7
ARPANET Interface


         Returns  0  if  successful,  error  number   otherwise.    If
                 successful,  8-bit  send  and receive TTY connections
                 are opened to the given foreign host.

     II.  CreateNetOutput and FindNetInput

         Arguments (two options):

         A.  For normal connections:

             (bytesize, foreign host, foreign  socket,  local  socket,
             OPENF ac2, waittime, polltime)

            1.  bytesize

                Either 8, 32, or 36 (BITS)

            2.  foreign host

                Either a BCPL string (the host name) in the rh and  -1
                in the lh, or a host number.

            3.  foreign socket

                An absolute foreign socket number.

         The remaining arguments are optional.  Casual or novice users
         can  probably ignore them and the subsequent discussion under
         "For normal connections":

         If an optional argument  is  omitted,  the  indicated  global
         variable is used in its place:

            1.  local socket default variable: NETLOCALSOCKET

                If specified, its form is to be

[directory number or 0 or -1],,[relative local socket number or -1]

               -1 in LH means job relative
                0 in LH means local directory relative
               >0 in LH means other directory relative
               -1 in RH means relative local socket number = 10*JFN

           5.  OPENF ac2

               default variable: Either NETINOPENF2  or  NETOUTOPENF2,
               for input and output, respectively.

               If specified, its form is to be  as  described  in  the
               TENEX JSYS Manual.

BCPL Reference Manual                               Page   8
ARPANET Interface


              NOTE:  The  value  of  AC2  when  OPENF  is  called   by
                    CreateNetOutput or FindNetInput includes the value
                    of the first argument (bytesize).  This is  shoved
                    into the appropriate bits of the fifth argument if
                    it  is  specified,  or  into  the  value  of   the
                    appropriate  OPENF2  global  variable.   The "data
                    mode" bits allow one to specify whether and how to
                    buffer    messages    (for    efficient    network
                    utilization), and whether to wait for matching RFC
                    or  CLS.   Note  that  NETWAITFLAG  is NOT used to
                    determine these bits.  For more  information,  see
                    the JSYS Manual.
           6.  waittime

               default variable:  NETWAITTIME  This  is  a  number  of
               milliseconds  to  wait  before giving up the attempt to
               establish the connection.

           7.  polltime default  variable:  NETPOLLTIME  This  is  the
               number  of  milliseconds  to  pause between attempts to
               establish the connection.

         B.  For LISTENING connections:

             (bytesize, LISTENING, localsocket, OPENF  ac2,  waittime,
             polltime)

             This is for opening a LISTENING connection.

            1.  The bytesize is either 8, 32, or 36 (BITS).

            2.  The second argument should be  the  MANIFEST  constant
                named LISTENING.

         The remaining arguments are  optional,  and  are  treated  as
         described above.

              Notes

                1.   Both  functions  return  either  a  BCPL   stream
                    descriptor  (  >0 ), or a negative error number if
                    they fail.

                2.   Normally,  these   functions   wait   until   the
                    connection    gets   established,   as   per   the
                    appropriate arguments or defaults.  The  functions
                    may be caused to return immediately by setting the
                    global variable named NETWAITFLAG to false.  It is
                    then the user's responsibility to check the status
                    of the network stream before doing  any  I/O  (see
                    NetStatus).   An  example  is  the  opening  of  a
                    LISTENING connection.  If  NETWAITFLAG  is  false,
                    the    waittime   and   polltime   arguments   are

BCPL Reference Manual                               Page   9
ARPANET Interface


                    meaningless.

Global Variables

     1.  NETLOCALSOCKET(initially [0,,-1])

      2.  NETINOPENF2(initially  6  ->  bits  6  thru  9  (data  mode:
          immediate return.  see the TENEX JSYS Manual.) 10 -> bits 19
          thru 22 (10 octal) (direction of connection) )
      3.  NETOUTOPENF2( initially same as above, except 4 -> bits
             19 thru 22)
      4.  NETWAITTIME(initially 20000) i.e.  20 seconds
      5.  NETPOLLTIME(initially 5000) i.e.  5 seconds
      6.  NETWAITFLAG(initially true)

          Defined Constant (manifest) LISTENING ← -1 a number distinct
          from any foreign host number, or from (-1,, BCPLstringptr)


     III.  LocalSocket

         LocalSocket(network stream) returns the absolute local socket
                 number  for  the  specified stream if it succeeds, or
                 the negative of the CVSKT JSYS  error  number  if  it
                 fails.


     IV.  NetStatus

         NetStatus(network stream,vector) returns  status  information
                 ala JSYS  145 (GDSTS) in the vector.  vector|1 is the
                 connection state  (see  the  document  on  the  TENEX
                 ARPANET   SOFTWARE   INTERFACE)   vector|2   is   the
                 connection byte size vector|3  is  the  foreign  host
                 number   vector|4   is   the  foreign  socket  number
                 NetStatus returns its second argument as its value.


     V.  EndNetDialogue

         EndNetDialogue(output stream, input  stream)  CLOSF  the  two
                 JFN's, and wait for them to close

     VI.  InitNetLibrary

         InitNetLibrary()  initialize  the  global  statics  to  their
                 default values.

BCPL Reference Manual                               Page  10
Formatted Output


C.1.5 Formatted Output


          TypeF(formatstring,arg1,arg2,....)
          PrintF(formatstring,arg1,arg2,....)
          PWriteF(formatstring,arg1,arg2,....)
          EndPrint()
          WriteF(stream,formatstring,arg1,arg2,arg3,....)
          OutputF(stream,formatstring,argvec,nvalues)



               These routines are intended to be  similar  to  FORTRAN
          WRITE  statements.   Stream  is  as  usual  in BCPL I/O.  In
          TypeF, #101 is  assumed  for  the  output  stream.   PWriteF
          assumes  the  static  OUTPUT as the stream (like PBOUT).  In
          PrintF, a printer stream is opened  the  first  time  it  is
          called,  (and  is remembered in a local static).  This stays
          open until all files are shut, or a reset is  done,  or  the
          JFN  is  closed,  or  the  printer  stream  is  closed using
          Endprint().  PrintF is meant to mirror the operation of  the
          FORTRAN PRINT statement.  All of these routines call OutputF
          which takes as its arguments, the stream, the format string,
          a vector of values (the first in argvec|1) and the number of
          values (including do loop iteration values).  OutputF can be
          called directly, if so desired.

               The format string is a BCPL string.  It is  similar  in
          form  to  the  FORTRAN format statement with some deletions,
          some additions, and some modifications.  The basic form of a
          single command field is as follows: 
          <FMT>::=
                          /           < T col >         \    
                         |                               |
                         |            / F [w|w.d] \      |
                         |           |  E [w|w.d]  |     |
                         |           /  I [w]      \     |
                         / [V[i|V]] <   O [w]       >    \
                        /            \             /      \
                        \            |  A [w|-w]   |      /
                         \            \ S [w|-w]  /      /
                         |                               |
                         |            / $(ch)    \       |
                         |           /  X         \      |
                         |           \  /         /      |
                         \            \ 'string' /      /     


          where upper case letters indicate those specific  characters

          and lower case letters are used to indicate integer numbers.


BCPL Reference Manual                               Page  11
Formatted Output


          Symbols or subfields enclosed in []  are  optional.   Larger

          brackets  means  "applies  to".   A "|" between two optional

          subfields means "or".  Using "<FMT>" for the basic  command,

          the  following  ways are available for combining them into a

          Total Format ("<TFMT>"):



          <TFMT>::=

                             [n] <FMT>

                             <TFMT>,<TFMT>

                             [n] (<TFMT>)



          Where the format would not be ambiguous  without  the  comma

          between  fields  it  is  not  necessary,  but  it  should be

          remembered that spaces are not delimiters.   It  is  assumed

          that  the  reader is familiar with FORTRAN FORMAT statements

          and only differences will  be  discussed.   (for  a  general

          description of FORTRAN FORMAT fields, see Appendix A.)


               T field: Will cause the next output  to  start  at  the

          column  specified.   The  first column is column 1.  This is

          accomplished by outputting spaces or a carriage  return  and

          spaces as is necessary.


               F field: The free format floating  point  output  (when

          w.d  is  not  given) uses the BCPL routine WriteR which uses

          the FLOUT JSYS with ac3=0.  It leaves no spaces.   If  w  Is

          specified,  and  .d  is  not,  then -1 is assumed.  (d=-1 is


BCPL Reference Manual                               Page  12
Formatted Output


          taken to mean no decimal point, but at present this  doesn't

          work and it works as if d = 0)


               E field: The exponent will always be given as  E+-  and

          two  digits.   There  is,  at  present,  no control over the

          exponent, so that the entire w columns will be filled  (with

          the  possible  exception  of  the  first  if  the  number is

          positive).  This may at some date be changed so  that  there

          is  one and only one integer digit given, with spaces to the

          left.  Free E format is E14.7 format or:   -i.dddddddE+ee   

            or     *si.dddddddE-ee


               I,O field: Integer  (radix  10  and  8,  respectively).

          There are no spaces with Free format.


               ASCIZ strings (A field) and BCPL strings (S field)  are

          significantly  different  from  FORTRAN.   If  width  is not

          specified, the entire string is output.

               w-width can be positive or negative.  If abs(w) is less

          than  the  length  of  the  string,  then  the  first abs(w)

          characters of the string are output.  If +w is greater  than

          the  length, the entire string is output, right-justified to

          w columns, filled to the left with spaces.  If -w is greater

          than  the  length,  the string is output left-justified, and

          padded to the right with spaces to make up w columns.


               '  -  literal  field:  Any  literal  string   of   BCPL

          characters  terminated  by a single quote (').  To include a


BCPL Reference Manual                               Page  13
Formatted Output


          single quote  in  the  string,  use  two  successive  single

          quotes('').  To include a double quote use (*")


               $ - single character field: The next BCPL character  in

          the  compiled  string will be taken as a literal and output.

          (special case of a literal field)


               X - field: Output a space.   (special  case  of  single

          character field)


               / - field: Outputs an EOL.   (special  case  of  single

          character field)


               V - vector field: If a V precedes a  data  field  type,

          then  instead  of  using the value in the argument list as a

          value, it is used as a pointer to a block of values.   If  i

          is  specified,  the  i successive values will be output with

          the following field specification.  The default is 1.   This

          counts  as  one  value  output  with  respect  to the format

          statement and argument list.  If instead of  an  integer  i,

          the  next  character  is  an  upper  or  lower  case V, this

          specifies a "variable vector length": the  value  after  the

          pointer value is taken as an integer and used as i (using up

          one of the arguments, of course).


               Iteration - Matching parentheses can be  nested  around

          parts  of  the  format  string.  If an integer is specified,

          this has the effect of  writing  out  the  enclosed  part  n

          times.   If  a  positive  integer  precedes  a field with no


BCPL Reference Manual                               Page  14
Formatted Output


          intervening left parenthesis, there are implied  parentheses

          around that one field.


               Termination    rules    -    A    comma    (or    right

          parenthesis-comma)  is  expected after all fields, so that a

          typical properly formed string would be:

                  "2(I5, 2x,f),/,3x,s"

               However, it is generally allowed for the  comma  to  be

          omitted  except  where  it must serve as a delimiter between

          two numbers.  Therefore

                  "2(I5, 2xf)/3xs"

          would accomplish the  same  goal.   Notice  that  the  comma

          between the 5 and the 2 is necessary, otherwise, it would be

          interpreted as

                  "2(I52, x,f),/,3x,s"

          even though there is a space.  Commas  (or  spaces)  may  be

          found  to  make the format string more readable, but this is

          left up to the user.


               General rules - All parentheses must be  matched.   All

          spaces  are  ignored  (except within literals) and therefore

          are not valid as delimiters.  All field type  specifications

          and the V can be upper or lower case.


               Error Handling - In the case of column  overflow,  free

          format is used.  Errors in the format string are detected at

          run time.  An error message will be output  to  the  primary

          output  stream  (OUTPUT),  followed  by  the  words  "Format


BCPL Reference Manual                               Page  15
Formatted Output


          Error", followed by the compiled string with "*↑*"  inserted

          immediately  following  the  character that is thought to be

          wrong.  The program then finishes (HALTF).  Typing  CONTINUE

          to  the  EXEC  will  cause execution to continue immediately

          after the call to WriteF.  (This will soon be changed to use

          the ERRSET facility in BCPL).


               Execution - continues until:

               a) The format string is exhausted.  If there are  still

          more  values left in the argument list, then processing will

          continue at the last left parenthesis on the same level,  if

          there  are  any.   If  the  last  non-space  is  not a right

          parenthesis, then execution will continue from the beginning

          of the format string.

          The following examples show where execution will continue if

          there are more values:


                 "F7.4, I5,2(3V2i2,1x, 2(s10,/))"
                           ↑


                 "F7.4,i5, 2(3Vvi2,3x,2(s-10, /) ), I "
                  ↑


                  " x, 2(I5, ' Here''s one*n'), t20, (f10,I2)"
                                                     ↑


               b) A field requiring a value is  encountered,  and  the

          argument  list  has  been exhausted.  One value is used each

          time  a  value-taking  specification  is  executed  in   the

          expanded  string.   The  vector  field iteration counts as 1


BCPL Reference Manual                               Page  16
Formatted Output


          field no matter how many values  are  used  from  the  value

          block.  If the variable vector length is used, then an extra

          value is used to get the number of values to be output  from

          the block.





               Examples:

          I) If there were two vectors of data x and y and  a  program

          were  comparing different values of the two arrays, then the

          call to WriteF and the corresponding output for 2 executions

          might look like this:


          WriteF(stream, "'Test Case No. ',I,/, 2(I5,f6.0,/),/", i,
           j,x|j, k,y|k)

                           Output
          Test Case No. 9
             24 3454.
            142  420.

          Test Case No. 10
            105-7523.
              7  -45.

          Here is what the following formatstring would produce with

           the same data:



          "'*nComparison *# ',i2, (t20,i,t26,f,/)"

                           Output


          Comparison #  9     24    3454.
                              142   420.

          Comparison #  10    105   -7523.
                              7     -45.

BCPL Reference Manual                               Page  17
Formatted Output


          II) In order to output a vector or part of vector, which

           would be done in FORTRAN by:

                  WRITE(1,10) (X(I), I = K,L)
          10      FORMAT(1X, F6.0)

                           Output
            34.5
           -20.7
          2473.0
          3650.0
           .
           .
          etc.

          Using WriteF this would be:

          WriteF(stream,"x,Vvf6.1,/", x+k, k-l+1)


          III) To put out two vectors and the subscript

           simultaneously:



                          FORTRAN

                 WRITE(1,10) (I,X(I),I,Y(I), I = 5,10)
          10     FORMAT(' X(',I2,') =',F7.4,2X,'Y(',I2,') =',F6.2)

                           Output
          X( 9) = 0.3425  Y( 9) = 12.45
          X(10) = 0.8739  Y(10) = -7.02

          Using WriteF this would be:

          for i ← 5 to 10 do
           WriteF(stream,"'x(',i2,') =',f7.4,2x,'y(',i2,') =',f6.2,/",i, x|i, i,
           y|i)



                    Appendix - A - Relevent FORTRAN format

           rules.

          Width  is  a  positive  integer  representing  the

           number of


BCPL Reference Manual                               Page  18
Formatted Output


          columns to be used in output, with the data

           right-justified.

          In floating point format, d specifies the  number 

           of

          decimal  digits  to  be output after the

           un-optional decimal

          point.  In all numeric fields, if the number is

           too big  for

          the  number  of columns specified, the w columns

           are instead

          filled with "*"'s.  If w is not specified, Free

           (variable width) format

          output follows the following conventions:

            E => E15.7

            F => F15.7

            I => I15

            O => O15


BCPL Reference Manual                               Page  19
Formatted Output


C.2 JSYS Interface

JSYS( JsysNumber, InputACs, OutputACs)
      Perform a JSYS call.
        JsysNumber: just that.  The file <BCPL>JSHEAD.BCP has a set of
            manifest declarations for the JSYS names.

        InputACs: A vector (of at least 10 cells) having the Values of
            the input AC's to the JSYS.
            v|1 equals AC1, v|2 equals AC2, etc.

        OutputACs: A vector (of at least 10 cells) for the Values of
            the output AC's from the JSYS.

      JSYS(n,v) is equivalent to JSYS(n,v,v)
      JSYS(n) allowed also (some JSYS's don't require parameters).

      Value: the number of instructions skipped plus one.

BCPL Reference Manual                               Page  20
JSYS Interface


C.3 Byte Manipulation

POINT(Size,Location,RightmostBit)
      Construct a PDP-10 byte pointer.  

        Size: the byte size (number of bits in a byte)

        Location: the Address of the cell containing the byte

        RightmostBit: the bit position in the cell of the right-most
            bit in the byte.  Bits in a cell are numbered from 0 to
            35, from left to right.  This argument may be absent; if
            so, it is assumed that you mean the first (leftmost) byte
            in the indicated word (Location).  POINT is meant to be
            the same as the POINT Pseudo-op in MACRO-10.

LDB(BytePtr)
      Extract a byte.  Value is the byte.

DPB(Byte, BytePtr)
      Deposit the specified byte.

ILDB( BytePtrLV)
      Increment the byte pointer and then extract a byte.  Value is
      the byte.

        BytePtrLV: The Address of a cell which contains the byte
            pointer.

IDPB(Byte, BytePtrLV)
      Increment the byte pointer and then deposit the specified byte.

IBP(BytePtrLV)
      Increment the byte pointer.

BCPL Reference Manual                               Page  21
Byte Manipulation


C.4 String Manipulation and Number Conversion

          Packstring
          Unpackstring
          StringToASCIZ
          ASCIZToString
          Eqstr
          TxtToInt
          findsubstr
          scanuntil
          changesubstr
          scanpastst
          pullch
          putch
          addch
          append
          inttotxt
          inttoocttxt

Conventions:

     Characters within a string are numbered starting at 1.  the
routines assume adequate storage for strings...e.g.  in append, the
output string is assumed large enough to hold the result.  BCPL
strings can be no bigger than 511 characters.  Beware: NO checking for
string buffer overflow or more than 511 characters is done.

Conversion routines for packed and unpacked BCPL strings:
         Vector|0 is character count [[unpacked format]]
         so is q4 (String|0) [[packed format]]
         Vector|n is the nth character in the string [[unpacked
         format]]

     Packstring
         Packstring(Vector,String) returns the string

     Unpackstring
         Unpackstring(String,Vector)

Conversion routines for BCPL and ASCIZ strings:

     StringToASCIZ
         StringToASCIZ(BcplString,VectorForASCIZString)
         returns the vector.

     ASCIZToString
         ASCIZToString(ASCIZString,VectorforBcplString)
         returns the vector.

     Eqstr
         Eqstr(string1,string2) returns true if the two  BCPL  strings
                                        ____
         are equal, false otherwise
                    _____

BCPL Reference Manual                               Page  22
String Manipulation and Number Conversion


     TxtToInt(string)
         This subroutine converts the indicated  text  string  into  a
         number.   Leading spaces or tabs are NOT allowed.  The string
         may be prefixed by a minus sign or a # character or by  both.
         The  minus  sign  means  negative,  and the # character means
         octal (default case is decimal).  If the lh of  the  argument
         is  negative,  the  right  half  is  used as the pointer to a
         vector, and the string is output unpacked (see Unpackstring).

     findsubstr(str,substr,slv,elv,scn)

         Find the indicated substring (substr) in the indicated string
         (str)-  start  searching  at  character  number  scn.  If the
         substring is found, return a ptr to its first character.   in
         rv  slv,  and  a  ptr  to  its  last character in rv elv, and
         resultis true, else resultis false.
                  ____                _____

     scanuntil(line,buffer,chnlv,c1,c2,c3, ...  )

         Search for one of (up to) 18 characters in a string  starting
         at  the indicated character position (rv chnlv).  If "buffer"
         is non-zero, it is taken as a vector in which a  BCPL  string
         having the scanned characters is to be constructed.  Resultis
         true if one of  the  indicated  characters  is  found,  false
         ____                                                    _____
         otherwise.   rv  chnlv is the character number of the located
                      __
         termination char.  If none is found, rv chnlv is unchanged.
                                              __

     changesubstr(str,srchsubstr,newsubstr)

         Change all instances of the indicated substring  (srchsubstr)
         in  the indicated string (str) to the indicated new substring
         (newsubstr).   Resultis  a  ptr   to   the   changed   string
         (newsubstr).

     scanpastst(line,chnlv)

         Search the indicated string (line), starting at the indicated
         character,(rv   chnlv).    Return  a  pointer  to  the  first
                    __
         non-space or tab character in rv chnlv.  It is  assumed  that
                                       __
         "line"  is a string which has at least one non-(space or tab)
         character.

     pullch(txt,cp)

         This fn returns the element (a character)  at  the  specified
         character position (cp) within the specified string (txt).

     putch(ch,txt,cp)

         This  procedure  replaces  the  character  at  the  specified
         character  position  (cp)  within  the specified string (txt)
         with the specified character (ch).

BCPL Reference Manual                               Page  23
String Manipulation and Number Conversion


     addch(ch, txt)

         Append the specified character (ch) to the  specified  string
         (txt).

     append(t1,t2,t3)

         Append the string t2 to the string t1 and store result in the
         string  t3.   Any  two  or all three specified strings can be
         identical.

     inttotxt(i,txt)

     inttoocttxt(i,txt)

         These functions convert the  indicated  number  into  a  text
         string in the indicated vector.  "inttotxt" generates decimal
         equivalent, "inttoocttxt" generates  octal  equivalent  (i.e.
         preceded  by  a  #  character).   If  required,  a minus sign
         appears.  The second argument (txt) is returned as the  Value
         of the function call.

     float(x)
         convert the specified integer (x) to a floating point number.
         Value: this number.

     fix(x)
         truncate the specified floating point number (x).  Value: the
         integer result.

     fixr(x)  
         same as fix, but with round-off

BCPL Reference Manual                               Page  24
String Manipulation and Number Conversion


C.5 Error Handling

Level()
      Returns value of stackpointer for current environment.  This  is
      needed (for example) for LongJump and LongDebrk (in PSI pkg.).

LongJump(label,level)
      Loads level into stackpointer (AC 16), then jumps to label.
      ALSO ERRSET AND ERROR!!

ERSTR(ErrorNumber) or ERSTR(stream,errornumber)
      Uses the ERSTR jsys.  Arguments are handled like WriteN.

Help(string)
      prints out the string, and a help  message,  and  then  HALTF's.
      CONTINUE will cause Help to return.

BCPL Reference Manual                               Page  25
Error Handling


C.6 BCPL Array Package

Dimension

sub

ArrayCheck


     A function (sub) is provided to compute a vector subscript for  a
multidimensional  "array,"  given  the  subscripts and a "dope vector"
describing the dimensions of the array.   A  function  (Dimension)  is
also  provided  for  forming dope vectors.  Arrays are indexed so that
for consecutive words in the vector, the  1st  subscript  varies  most
rapidly,  as  in  FORTRAN.   There  is  a limit of 10 on the number of
dimensions.
Array bound checking is performed given either of two conditions:
      1.  Global variable ArrayCheck has  the  Value  true  (initially
                                                      ____
          false).
          _____
      2.  The zeroth element of the dope vector is minus the number of
          dimensions.   This  can be accomplished by giving a negative
          first argument to the function "Dimension".

The function Dimension forms a dope vector.  Arguments:

dopevec  =  a  vector  which  will  be  stuffed  with  the   dimension
          information.  Must be of length 2*ndimensions+3
          If dopevec is given as -vector, then the dope vector will be
          flagged to cause array bound checks to be done.

There follow pairs of minimum and maximum subscript values for as many
dimensions as the array is to have.

The resulting dope vector has the following form:
     ndims,     min1,     1,      min2,      (max1-min1+1),      min3,
     (max1-min1+1)*(max2-min2+1)               ,...,              Nil,
     (max1-min1+1)*...*(maxN-minN+1)

The function sub computes the vector element given the dope vector and
the array subscript(s).

     For example:
          let foo,foodim←vec 121,vec 7
          Dimension(foodim,0,10,-5,5)
          for i←0 to 10 do for j←-5 to 5 do
          { foo|sub(foodim,i,j)←i,,j⎇


BCPL Reference Manual                               Page  26
Arrays


C.7 Hash-Coded Dictionary
          DictGetFree
          DictRetFree
          TBP
          InitDict
          RestoreDict
          Enter
          Find
          NextDictEntry

     The BCPL dictionary package is a collection of subroutines which
 are used to construct and maintain a hash-coded dictionary. This
 dictionary
provides a mechanism for relating a specified BCPL string to a
 "dictionary entry" (via Enter and Find). 
This entry is a block of adjacent cells which has two parts: a header
 of at least one cell, followed (in memory) by enough cells to store
 the string. The right-most quarter of the zeroth cell of the header
 is used to store the 
number of cells in the header. 

     The "get" file of GLOBAL and EXTERNAL declarations for the
 dictionary package
is <BCPL>DICTHEAD.BCP. The BCPL library contains the dictionary
 package; it will be loaded
automatically with your program if you need it.

     The dictionary package deals with relative pointers. The idea is
 that a dictionary
may reside anywhere in memory.
 Indeed, the program can deal with several
dictionaries, each residing in a different portion of memory, by
specifying the base address for the relative pointers in the new
 dictionary
of interest when a switch between dictionaries is made (via
 RestoreDict).
Accordingly, when the user constructs and initializes a new dictionary
(via InitDict), he specifies its base address; if he doesn't want to
 deal
with relative pointers, the base address should be zero.

     The dictionary package uses a free storage allocation mechanism
 which
must be provided by the user. This leaves the user free to define his 
own free storage strategy, and decide from whence free storage cometh.
 There is a standard free storage allocation package for TENEX BCPL,
 described in section C.8 below. 

     The free storage mechanism for the dictionary is two subroutines,
 referenced as GLOBALs by the dictionary package, and expected to be
 defined by the user and loaded along with his program:

BCPL Reference Manual                               Page  27
Hash-coded Dictionary


DictGetFree(n)
    should return a pointer to a block of n registers

DictRetFree(pointer)
    should put the indicated block of registers back into the free
     storage pool

     The subroutines which are provided by the dictionary package are
 presented below:
InitDict(hashsize,offset)
    purpose: create and initialize a new dictionary

      hashsize: size of the primary hash table. For best results, this
           should be roughly 50% bigger than the number of entries
           expected.
      offset: base address for dictionary pointers

    Value:  a relative pointer to the primary hash table (called
           "hashstart" below). (Note: InitDict will call DictGetFree
           to allocate storage for this table).

RestoreDict(hashsize,offset,hashstart)
    purpose:  reset the dictionary package to consider an old
              (previously initialized) dictionary. This is useful when
               dealing with
              more than one dictionary, when you want to switch
               between them.

      hashstart: a relative pointer to the primary hash table

    Value: hashsize.

Enter(wrd,address,datalength)
    purpose: enter a given word in the dictionary
      wrd: a pointer to a BCPL string

      address: the address of a storage cell into which to store a
           relative pointer to the dictionary entry.

      datalength: The number of cells to allocate (except for the
           rightmost quarter of the zeroth cell) for the
          header of the dictionary entry.

    The Value is a Boolean:
          true => it was found to be already entered
          ____
          false => it was not found to be already entered.
          _____

Find(wrd,address)
    purpose: find the dictionary entry for a given word

      wrd,address: same as for Enter

BCPL Reference Manual                               Page  28
Hash-coded Dictionary


    The Value is the same as for Enter.

Delete(wrd,address)
    purpose: delete the dictionary entry for a given word

      wrd,address: as above

    Value:
      true => it was found and deleted
      ____
      false => it was not found
      _____

               NOTE: even though a pointer to the entry is returned in
                the specified storage cell,
               the storage for the entry will have been reclaimed
                (i.e. a call will have been made on DictRetFree) by
                the time Delete returns.

NextDictEntry(firstblv,entrylv)
    purpose: find all the dictionary entries, one at a time, in an
     undefined order

      firstblv: the Address of a storage cell which should contain
           true for the first call on NextDictEntry, and false for
           ____                                          _____
           subsequent calls. NextDictEntry will set the Value of the
           storage cell to false before
                           _____
          it returns the first time.

      entrylv: the Address of a storage cell into which to store a
           relative pointer to the next dictionary entry. Meaningful
           only if the result of the call on NextDictEntry is true.
                                                              ____

    Value: true if there is a next entry, false otherwise.
           ____                           _____

    Example: ["base" has the dictionary base address as its value]

         // print out all entries in a dictionary
         { let b←true
           ___   ____
           let entry←nil
           ___       ___
           while NextDictEntry(lv b, lv entry) do
           _____               __    __        __
            { WriteS(base+entry+q1z base|entry)
                                ___
              PBOUT($*n)
            ⎇
         ⎇


     (The following discussion is for users who want  to  replace  the
dictionary package's hash-coding algorithm with their own).

     The dictionary subroutines hash-code the  input  BCPL  string  to
yield  an address into the "primary hash table".  This table is marked
to indicate (for each entry) whether it is full, and, ifso,  where  an
overflow  ("secondary")  hash table is for that entry.  The subroutine
which does the hash coding is named TBP, is referenced as an  EXTERNAL

BCPL Reference Manual                               Page  29
Hash-coded Dictionary


by the dictionary package, and a standard version of it is part of the
BCPL library.  The user is free to define his own TBP subroutine,  and
load  it with his program.  For a user who wants to do this, the specs
for TBP are presented below:

TBP()
    returns an address relative to the start of the hash  table  whose
    length  is  the value of GLOBAL #352, where a pointer to the input
    string is the value of GLOBAL #351, and where the value of  GLOBAL
    #350  is the number of registers used to hold the string, minus 1.
    This equals:

               (q4 GL351|0)/4

BCPL Reference Manual                               Page  30
Hash-coded Dictionary


C.8 Free Storage Allocation
          GetBlock
          RetBlock
          ResetFreeStore
          GetStorageSpace

     This package is meant  to  manage  memory  allocation;  the  user
specifies large regions of memory (via GetStorageSpace) that are to be
carved up into blocks (via GetBlock) in  response  to  his  subsequent
requests.   No  "garbage  collection"  is done; i.e.  it is the user's
responsibility to explicitly release blocks of storage when  they  are
no longer needed (via RetBlock).

     The BCPL free storage package consists of three subroutines:

     1.  GetBlock(n)
         returns a pointer to a block of n storage cells

     2.  RetBlock(pointer)
         reclaims a free storage block which was previously  allocated
         by GetBlock

     3.  ResetFreeStore()
         This re-initializes the free storage routines.

     The "get" file  of  GLOBAL  declarations  for  the  free  storage
package is

         <BCPL>FREESTOREHEAD.BCP

     The BCPL library contains the free storage package;  it  will  be
loaded automatically with your program if you need it.

     The free storage package expects that the  user  will  provide  a
subroutine for allocating big chunks of memory for its use:

     4.  GetStorageSpace(npages)
         Value should be a pointer to a new chunk  of  memory  of  the
         specified  number  of  pages.  Currently, the npages argument
         will be 16.

BCPL Reference Manual                               Page  31
Free Storage Allocation


C.9 PSI System Interface
          PSICHN
          PSILEV
          PSIPC
          FNTBL
          PSICH0
          PSISetCh
          PSIOn
          PSIOff
          PSIClear
          PSIChEnb
          PSIChDis
          PSIChInit
          IsPSIChEnb
          FreeTICh
          ATI
          DTI

               The   software   support   for   use   of   the   TENEX
          pseudo-interrupt system from a BCPL environment comes in two
          pieces.  The  first,  named  BPSI,  is  a  machine  language
          component which is necessary for PSI operation.  The second,
          named PSI, is a set of BCPL functions and subroutines  which
          interface  to  the  pseudo-interrupt  system  JSYS's.   Both
          packages  reside  in  the  BCPL  library,  and  are   loaded
          automatically   when  a  BCPL  program  in  which  they  are
          referenced  is  loaded.   Such  a   program   should   "get"
          <BCPL>PSIHEAD.BCP.   For  a detailed discussion of the TENEX
          PSI system, see Chapter 5 of the TENEX JSYS Manual.


          BPSI: the basic machine language package
          _____ ___ _____ _______ ________ _______

               The basic operation of a pseudo-interrupt is:  When  an
          interrupt  occurs,  a  table  is consulted for an address to
          which control is transferred.  The  section  of  program  so
          selected   saves   any   AC's  it  needs,  carries  out  its
          processing, then either restores AC's and  debreaks  to  the
          previous  environment,  or initializes any AC's it needs and
          debreaks to an arbitrary address.  In  a  BCPL  environment,
          this  needs  to get translated to: When an interrupt occurs,
          consult a table for the name of a BCPL subroutine, and cause
          it  to  be  run.   If  it  returns,  restore to the previous
          environment.  Also provide a means by  which  the  interrupt
          can be debreaked (debroken?) and control transferred to some
          arbitrary label.  These services are provided  by  the  BPSI
          package.

               BPSI  contains  the  following,  which   are   declared
          external in <BCPL>PSIHEAD.BCP:

      a. PSICHN - PSICHN|i, i=0,1,...,35 is the PSI channel table.

BCPL Reference Manual                               Page  32
PSI Handling


      b. PSILEV - PSILEV|i, i=1,2,3 is the PSI level table.

      c. PSIPC - PSIPC|i, i=1,2,3 holds the PC for level i.

      d. FNTBL  -  FNTBL|i,  i=0,1,...,35,  contains  a  JRST  to  the
         subroutine to be executed upon interrupt on channel i.

      e. PSICH0 -  An  interrupt  on  channel  i  should  transfer  to
         location 4*i + lv PSICH0.

     In order to set up an interrupt on channel  C,  at  level  L,  to
execute routine R, do the following:

      1. Set PSICHN|C to L,,4*C + lv PSICH0.

      2. Set FNTBL|C to R.

      3. Enable PSI channel C using the  AIC  JSYS.   If  not  already
         done,  set  up the entire PSI system with the SIR JSYS (AC2 =
         lv PSILEV|1,,lv PSICHN|0) and enable it with EIR.

     When the interrupt occurs, the routine  R  will  be  called  with
three arguments:

     1. Level of interrupt

     2. Channel of interrupt

     3. Lv of the PC storage word for this interrupt.

     To return from the interrupt, the routine R merely  returns.   Of
course,  it  can  not return a value.  To transfer to some label, with
which  is  associated  a  level  (stack  pointer),  call  the  routine
                          _____
LongDebrk(pclv,label,level), where:

      pclv = Lv of the PC storage word

      label = The label to be transferred to

      level = The level associated with the  label  (may  be  obtained
         from the function Level() in <BCPL>UTIL.)

***WARNING***:  The  present  implementation  of  BPSI  contains   the
_____________
following  fudge:  when  the  interrupt subroutine is run, a new stack
frame is made for it by  adding  50000  to  the  existing  one.   This
obviously  will  fail  in  cases where the current stack frame is very
large.  Beware of this until the BCPL code generator  is  modified  to
provide a solution to this potential bug.  You have been warned!


PSI: the user routines
____ ___ ____ ________

BCPL Reference Manual                               Page  33
PSI Handling


     PSI contains a number of functions and subroutines which  act  as
an  interface  between  the  user  and  the  JSYS's  which control the
pseudo-interrupt system.  Use of this package  is  not  necessary  for
pseudo-interrupt  usage,  as  is BPSI.  The information given above is
sufficient for the user to implement direct calls to  the  appropriate
JSYS's.   Although  the  functions  and  routines  described  here are
intended to cover the most common  types  of  pseudo-interrupt  usage,
they  are  not  exhaustive or completely general.  In order to realize
the full flexibility of the TENEX pseudo-interrupt  system,  the  user
may  have  to  supplement  them  with  other  direct  JSYS  calls.  In
particular these routines do not give access to the JSYS's RWM, SIRCM,
RIRCM, STIW, or RTIW.

     The default,  where  appropriate,  is  for  all  pseudo-interrupt
operations  to  refer  to the current fork.  However, PSISetCh, PSIOn,
PSIOff, IsPSIOn, PSIChEnb, PSIChDis,  PSIChInit,  and  IsPSIChEnb  can
take  a  fork  handle as an optional first argument in addition to the
arguments shown below.

     PSISetCh(level,channel,routine) - set up for an interrupt on  the
     given  level and channel, to dispatch to the given routine.  Also
     enable the channel.

     PSIOn() - declares the level and channel tables and  enables  the
     pseudo-interrupt system.

     PSIOff() - disables the pseudo-interrupt system.

     PSIClear() - clears all interrupts in  process  and  all  waiting
     interrupts.

     PSIChEnb(channel1,channel2,...) - enables channel(s) given by the
     argument(s).

     PSIChDis(channel1,channel2,...) - disables  channel(s)  given  by
     the argument(s).

     PSIChInit(channel1,channel2,...) - initiates interrupt(s) on  the
     channel(s) given by the argument(s).

     boolean←IsPSIChEnb(channel) - returns true  if  the  channel  has
     been enabled.

     value←FreeTICh() - returns the number of a free channel which may
     be  used  for a terminal interrupt.  terminates with a message if
     none is free.

     ATI(character,channel)  -  assigns   the   character   to   cause
     interrupts  on  the given channel and sets the terminal interrupt
     word (nondeferred) for  that  character.   Does  not  enable  the
     channel.   Terminates  with a message if character is not a valid
     terminal interrupt character.

BCPL Reference Manual                               Page  34
PSI Handling


     DTI(character) - breaks the assignment of character  to  whatever
     channel it was assigned to.

BCPL Reference Manual                               Page  35
PSI Handling


Example program:



get "<BCPL>HEAD"
get "<BCPL>UTILHEAD"
get "<BCPL>PSIHEAD"

manifest{ rubout← 177⎇
static { savedlabel←nil; savedlevel←nil⎇

let Start() be
{ OUTPUT← 101
  let foo←$A-1
  let rubchnl←FreeTICh()  //Find a free channel for rubout int.
  ATI(rubout,rubchnl)  //Assign rubout to it
  PSISetCh(1,rubchnl,rubint)  //Level 1, that channel, to rubint
  PSIOn()
  savedlabel←here
  savedlevel←Level()
here:
  Writech($*n)  //Ridiculous program just
  foo←foo+1  // to have something to do
  for i←1 to 72 do  // til user types rubouts to
  { Writech(foo)  // show that PSI's work!
    Wait(2000)
  ⎇
  goto here
⎇

and rubint(l,c,lvpc) be  //rubout causes this routine
{ WriteS("*sXXX")  // to be run
  LongDebrk(lvpc,savedlabel,savedlevel)
⎇

BCPL Reference Manual                               Page  36
PSI Handling


C.10 Miscellany

      InitACs
               InitACs is a vector containing the initial AC's
               InitACs|0 ← AC0 on start-up ...
               in addition, InitACs|16 ← base of the runtime
               stack

      ACCall(subr,v,v)
            Similar to JSYS, except first argument
            (subr)is the Value of a subroutine which expects
             to be called via

                 PUSHJ 17,subr

            and expects arguments in AC's

      TLOCK(lv LockWord)
               Does an "AOSE" (add 1 and skip if result equals zero)
             on LockWord, and returns true
                                      ____
                 if the AOSE skips, false otherwise.
                                    _____

       FArg(type, variablelv)
            ************type************
              Packs up the argument in a form
              to put into the vector argument to 
              FCall

       FCall(globalval,argvec,ac1lv)
            Value←FCall (...) call a FORTRAN Function or subroutine
             argvec|0 = number of arguments
             argvec|1 = first argument, ala FortranArg
                (etc.)
             ac1lv is the lv of a variable into which to
             stuff ac1 on return from the FORTRAN function call.
             Optional argument. Useful for
             Fortran functions which return
             double precision or complex results.
             globalval should be the Fortran subroutine 
             entry address.

      blt(from,to,last,safe)

            like the PDP-10 BLT instruction. The fourth argument
             (safe) is optional.
             if present, do a check for overlapped blt and do the
             right thing if necessary

      NumbArgs()
             no arguments. The Value returned is the number of
             arguments in the most recent call on the function or
             routine
               which called NumbArgs.

BCPL Reference Manual                               Page  37
Miscellany


       Wait(number of milliseconds)

       MakeDate(v,d)
             builds a BCPL string of the specified date
              and time (d) (using the ODTIM JSYS)in the
              specified string (v). If d is missing, the
              current date and time is used. This also happens
              if d is zero.
              MakeDate returns its first argument.

      Date()
             returns the current date and time ala TENEX. (a 36
              bit number).

      min(arg1,arg2,arg3,...)
            Returns the minimum of the arguments.  Assumes
             args are either all integer or all floating point.

      max(arg1,arg2,arg3,...)
            as above, but maximum.